标签:node pos 2.3 两种 family logs 技术 技术分享 class
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1505 Accepted Submission(s): 456
细节!!!
啊啊啊啊!!!用了一天的时间终于调出来了啊!!!可恶的一道题!!!细节实在是太恶心了!!!
2. 十分显然,在第一种走法中间又有坑逼之处!!!就是i这个点在计算向下走的价值的时候要如何处理!!!
就是这个东西卡了我一个下午!!!QAQ!!!
给点提醒吧,
1 在求f_down[i][1]的时候,要把最后向下的边(edge1)给记下来,还要记下如果没有(edge1)那么f_down[i][1]的最后向下的边是哪一条!!!
2 在计算1(就是上面那玩儿)的时候,比如求到了点s[i].v最好判断一下点s[i].v能不能在保证有价值的情况下返回i点。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define maxn 100100 << 1 using namespace std; int n,head[maxn],tot,u,v,val,dian[maxn],fir[maxn],sec[maxn]; int f_down[maxn][3],f_up[maxn][3],f_edge[maxn]; // 0表示返回原点,1表示不返回原点 struct st{ int v,val,next; st in(int a,int b,int c) { v = a; val = b; next = c; } }s[maxn]; inline void add(int u,int v,int val) { tot++; s[tot].in(v,val,head[u]); head[u] = tot; } void dfs(int fa,int now) { f_down[now][0] = f_down[now][1] = dian[now]; int k = 0,ma = 0; int pos; for(int i=head[now];i;i=s[i].next) { if(s[i].v != fa) { f_edge[s[i].v] = s[i].val; dfs(now,s[i].v); f_down[now][0] += max(f_down[s[i].v][0] - 2 * s[i].val,0); f_down[now][1] += max(f_down[s[i].v][0] - 2 * s[i].val,0); if(k < f_down[s[i].v][1] + f_edge[s[i].v] - f_down[s[i].v][0] && f_down[s[i].v][0] - 2 * s[i].val > 0) { k = f_down[s[i].v][1] + f_edge[s[i].v] - f_down[s[i].v][0]; sec[now] = s[i].v; if(k > ma) { swap(k,ma); swap(sec[now],fir[now]); } pos = fir[now]; } if(f_down[s[i].v][0] - 2 * s[i].val <= 0 && f_down[s[i].v][1] - s[i].val > 0) { if(k == 0) { k = f_down[s[i].v][1] - s[i].val; sec[now] = s[i].v; if(k > ma) { swap(k,ma); swap(sec[now],fir[now]); } pos = fir[now]; } else if(k < f_down[s[i].v][1] - s[i].val) { k = f_down[s[i].v][1] - s[i].val; sec[now] = s[i].v; if(k > ma) { swap(k,ma); swap(sec[now],fir[now]); } pos = fir[now]; } } } } if(ma != 0) f_down[now][1] = f_down[now][1] + ma; } int get_up(int fa,int now) { int ans = f_up[fa][1] - dian[fa] + f_down[fa][0] - dian[fa]; if(f_down[now][0] - 2 * f_edge[now] > 0) ans -= f_down[now][0] - 2 * f_edge[now]; return ans; } int get_down(int fa,int now) { int ans = f_up[fa][0] - dian[fa] + f_down[fa][1] - dian[fa]; if(fir[fa] == now) { int k = sec[fa]; ans -= f_down[now][1] - f_edge[now]; ans = ans - max(0,f_down[k][0] - 2 * f_edge[k]) + f_down[k][1] - f_edge[k]; } else if(f_down[now][0] - 2 * f_edge[now] > 0) ans -= f_down[now][0] - 2 * f_edge[now]; return ans; } void find(int fa,int now) { f_up[now][0] = f_up[now][1] = dian[now]; int k = f_down[fa][0]; if(fa) { if(f_down[now][0] - 2 * f_edge[now] > 0) k -= f_down[now][0] - 2 * f_edge[now]; f_up[now][0] += max(0,k - 2 * f_edge[now] + f_up[fa][0] - dian[fa]); f_up[now][1] += max(0,max(get_up(fa,now),get_down(fa,now)) - f_edge[now] + dian[fa]); } for(int i=head[now];i;i=s[i].next) { if(s[i].v != fa) find(now,s[i].v); } } int main(){ int t; cin >> t; for(int qwer=1;qwer<=t;qwer++) { tot = 0; memset(head,0,sizeof(head)); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&dian[i]),fir[i] = sec[i] = 0; for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&val); add(u,v,val); add(v,u,val); } dfs(0,1); find(0,1); printf("Case #%d:\n",qwer); for(int i=1;i<=n;i++) printf("%d\n",max(f_down[i][0] + f_up[i][1],f_down[i][1] + f_up[i][0]) - dian[i]); } } /* 3 4 5 3 4 4 1 2 1 1 3 2 1 4 1 8 13 13 13 13 13 13 13 13 1 2 5 1 3 6 2 4 7 2 5 8 2 6 9 3 7 5 3 8 5 5 4 1 7 7 7 1 2 6 1 3 1 2 4 8 3 5 2 */
HDU 5834 Magic boy Bi Luo with his excited tree
标签:node pos 2.3 两种 family logs 技术 技术分享 class
原文地址:http://www.cnblogs.com/kczno1fans/p/7780609.html