洛谷P1131 [ZJOI2007]时态同步
树形DP..
设dp[i]表示从i到以i为根的子树的最远距离就好
转移dp[i]=max(dp[i],dp[e]+edge[i].len);
最后在遍历加一下答案就好。
记得开long long
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #define maxn 500010 using namespace std; struct node { int ed,nxt; long long len; }; node edge[maxn<<1]; int n,m,first[maxn],cnt; long long dp[maxn]; long long ans; inline void add_edge(int s,int e,long long l) { ++cnt; edge[cnt].ed=e; edge[cnt].len=l; edge[cnt].nxt=first[s]; first[s]=cnt; return; } inline void dfs(int now,int fa) { for(register int i=first[now];i;i=edge[i].nxt) { int e=edge[i].ed; if(e!=fa) { dfs(e,now); dp[now]=max(dp[now],dp[e]+edge[i].len); } } for(register int i=first[now];i;i=edge[i].nxt) { int e=edge[i].ed; if(e!=fa) ans=ans+dp[now]-(dp[e]+edge[i].len); } return; } int main() { scanf("%d%d",&n,&m); for(register int i=1;i<=n-1;++i) { int s,e; long long l; scanf("%d%d%lld",&s,&e,&l); add_edge(s,e,l); add_edge(e,s,l); } dfs(m,0); printf("%lld\n",ans); return 0; }