本文主要是介绍AW287 积蓄程度,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目地址
易错点:
- 注意预处理时的边界条件(if(degree[y]==1)D[x]+=e[i].w;else D[x]+=min(D[y],e[i].w);).
- 笔者由于边数组开了3e5而调试了近半个小时.
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=4e5+10,INF=1<<30;
struct Edge{int from,to,w,nxt;
}e[MAXN];
int edgeCnt=1,head[MAXN];
void addEdge(int x,int y,int w){e[++edgeCnt].from=x;e[edgeCnt].to=y;e[edgeCnt].w=w;e[edgeCnt].nxt=head[x];head[x]=edgeCnt;
}
int D[MAXN],degree[MAXN];
bool vis1[MAXN];
int f[MAXN];
void dfs(int x){vis1[x]=1;for(int i=head[x];i;i=e[i].nxt){int y=e[i].to;if(vis1[y])continue;dfs(y);if(degree[y]==1)D[x]+=e[i].w;else D[x]+=min(D[y],e[i].w);}
}
int ans=-INF;
bool vis2[MAXN];
void dp(int x){vis2[x]=1;ans=max(ans,f[x]);for(int i=head[x];i;i=e[i].nxt){int y=e[i].to;if(f[y]||vis2[y])continue;f[y]=D[y]+min(e[i].w,f[x]-min(e[i].w,D[i]));dp(y);}
}
int n;
void init(){edgeCnt=1;ans=-INF;for(int i=1;i<=n;i++){head[i]=vis1[i]=vis2[i]=degree[i]=f[i]=D[i]=0;}
}
int main(){int t;scanf("%d",&t);while(t--){scanf("%d",&n);init();for(int i=1;i<=n-1;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);addEdge(x,y,z);addEdge(y,x,z);degree[x]++,degree[y]++;}dfs(1);f[1]=D[1];dp(1);printf("%d\n",ans);}return 0;
}
这篇关于AW287 积蓄程度的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!