【DP】 BZOJ 1487: [HNOI2009]无归岛
2015-07-27 16:48
169 查看
基环+外向树。。。。。先树形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;} // head struct 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; }
相关文章推荐
- iPad开发强制横屏
- 背包问题
- 在Netbeans IDE上安装node.js
- 黄聪:wordpress前台自定义用户,调用wp_editor上传附件提示【抱歉,出于安全的考虑,不支持此文件类型】错误。
- 忽然领悟了云的含义
- 【LeetCode 241】Different Ways to Add Parentheses
- CAS流程源码分析。
- Android View.onMeasure方法的理解
- SVN与其他工具整合
- maven常见命令
- 图结构练习——判断给定图是否存在合法拓扑序列
- Android API Guides 阅读笔记(4)----Fragment
- Jetty和Tomcat的选择
- 设置滚动效果
- Document.getElementById 与 $('#id')的区别
- 重拾Excel之为什么
- 几个不常用但是很好用的PHP数组函数
- 《Java Concurrency in Practice》之线程封闭(Thread Confinement)
- VIM常用方法记录
- GTK常用控件之窗口( GtkWindow )