标签:play struct \n string str 数据 event closed style
这个题。。。一眼树形DP???
我们通过模拟几组数据可以发现。。。
其实只需要保证每一棵树的边权之和加起来相等。。。
那么这些子树组成的一棵大树。。。就是最终我们要求的。。。
既然这样。。。
我们第一遍需要从叶子结点推到根节点。。。找到这些最大值。。。
我们便于理解。。。这里将树分级。。。叶子结点为1级。。。比它大一号的为2级。。。
以此类推。。。
然后依次枚举每一个以当前节点为根的n级子树的权值和它所在n+1级子树要达到的最大值
这样就可以统计出答案了。。。
代码:
#include<iostream> #include<cstdio> #include<cstring> #define maxn 500010 using namespace std; int n,s,x,y,z,f[maxn],head[maxn<<1],num; long long ans; bool use[maxn]; struct asd{ int nxt; int to; int dis; } a[maxn<<1]; inline void add(int x,int y,int z) { a[++num].nxt=head[x]; a[num].to=y; a[num].dis=z; head[x]=num; } inline void dfs1(int u) { use[u]=1; for(int i=head[u];i;i=a[i].nxt) { int to=a[i].to; if(!use[to]) { dfs1(to); f[u]=max(f[u],f[to]+a[i].dis); } } } inline void dfs2(int u) { use[u]=1; for(int i=head[u];i;i=a[i].nxt) { int to=a[i].to; if(!use[to]) { dfs2(to); ans+=f[u]-f[to]-a[i].dis; } } } int main() { scanf("%d%d",&n,&s); for(int i=1;i<=n-1;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } dfs1(s); memset(use,0,sizeof(use)); dfs2(s); printf("%lld\n",ans); return 0; }
标签:play struct \n string str 数据 event closed style
原文地址:https://www.cnblogs.com/zzzyc/p/9029174.html