【DP】 BZOJ 1487: [HNOI2009]无归岛

来源:互联网 发布:联通网络ip地址丢失 编辑:程序博客网 时间:2024/05/20 18:48

基环+外向树。。。。。先树形dp再环形dp。。。。

#include <iostream>#include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits>#include <cstdlib>#include <cmath>#include <time.h>#define maxn 100005#define maxm 500005#define eps 1e-7#define mod 1000000007#define INF 0x3f3f3f3f#define PI (acos(-1.0))#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R#define pii pair<int, int>#pragma comment(linker, "/STACK:16777216")typedef long long LL;typedef unsigned long long ULL;//typedef int LL;using namespace std;LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}// headstruct Edge{int v;Edge *next;}E[maxm], *H[maxn], *edges;int dfn[maxn];int low[maxn];int val[maxn];int f[2][maxn];int fa[maxn];int a[maxn];int n, m, dfs_clock;void addedges(int u, int v){edges->v = v;edges->next = H[u];H[u] = edges++;}void init(){dfs_clock = 0;edges = E;memset(H, 0, sizeof H);memset(f, 0, sizeof f);memset(dfn, 0, sizeof dfn);}void dp(int cnt){//for(int i = 0; i < cnt; i++) printf("PPP %d %d\n", f[0][a[i]], f[1][a[i]]);int res1 = 0, res2 = 0, t1, t2;for(int i = 1; i < cnt; i++) {t1 = max(res1, res2) + f[0][a[i]];t2 = res1 + f[1][a[i]];res1 = t1, res2 = t2;}f[0][a[0]] += max(res1, res2);res1 = res2 = 0;for(int i = 2; i < cnt - 1; i++) {t1 = max(res1, res2) + f[0][a[i]];t2 = res1 + f[1][a[i]];res1 = t1, res2 = t2;}f[1][a[0]] += max(res1, res2) + f[0][a[1]] + f[0][a[cnt-1]];}void dfs(int u){dfn[u] = low[u] = ++dfs_clock;for(Edge *e = H[u]; e; e = e->next) if(e->v != fa[u]) {int v = e->v;if(!dfn[v]) {fa[v] = u;dfs(v);low[u] = min(low[u], low[v]);}else low[u] = min(low[u], dfn[v]);}f[0][u] = 0, f[1][u] = val[u];for(Edge *e = H[u]; e; e = e->next) if(e->v != fa[u]) {int v = e->v;if(u == fa[v] && dfn[u] < low[v]) {f[0][u] += max(f[0][v], f[1][v]);f[1][u] += f[0][v];}}for(Edge *e = H[u]; e; e = e->next) if(e->v != fa[u]) {int v = e->v;if(u != fa[v] && dfn[u] == low[v]) {int cnt = 0, vn = v;a[cnt++] = u;do {a[cnt++] = vn;vn = fa[vn];}while(vn != u);dp(cnt);}}}void work(){int u, v;while(m--) {scanf("%d%d", &u, &v);addedges(u, v);addedges(v, u);}for(int i = 1; i <= n; i++) scanf("%d", &val[i]), val[i] = max(0, val[i]);fa[1] = 0;dfs(1);int ans = max(f[0][1], f[1][1]);printf("%d\n", ans);}int main(){while(scanf("%d%d", &n, &m) != EOF) {init();work();}return 0;}


0 0
原创粉丝点击