这是一道二次扫描与换根法的裸题,见《算法竞赛进阶指南》第三版p290
主要是作为参考代码.(本代码转载自http://www.cnblogs.com/lmjer/p/9418902.html,并进行了一定的修改)
题目地址:http://poj.org/problem?id=3585
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=500010;
int cnt,ans,head[maxn],d[maxn],f[maxn],deg[maxn];
bool vis[maxn];
struct Edge{
int from,to,w,nxt;
}e[maxn*2];
void addEdge(int u,int v,int w){
e[++cnt].from=u;
e[cnt].to=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
void dfs1(int x){
vis[x]=1;
for(int i=head[x];i;i=e[i].nxt){
if(vis[e[i].to])continue;
int v=e[i].to;
dfs1(v);
if(deg[v]==1)d[x]+=e[i].w;
else d[x]+=min(d[v],e[i].w);
}
}
void dfs2(int x){
vis[x]=1;
for(int i=head[x];i;i=e[i].nxt){
int v=e[i].to;
if(vis[v])continue;
if(deg[x]==1)f[v]=d[v]+e[i].w;
else f[v]=d[v]+min(e[i].w,f[x]-min(e[i].w,d[v]));
ans=max(ans,f[v]);
dfs2(v);
}
}
void clearAll(){
ans=0,cnt=0;
memset(head,0,sizeof(head));
memset(d,0,sizeof(d));
memset(f,0,sizeof(f));
memset(deg,0,sizeof(deg));
memset(vis,0,sizeof(vis));
}
int main(){
int t;
scanf("%d",&t);
while(t--){
clearAll();
int n;
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w);
addEdge(v,u,w);
deg[u]++;
deg[v]++;
}
int root=1;
dfs1(root);
memset(vis,0,sizeof(vis));
f[root]=d[root];
dfs2(root);
printf("%d\n",ans);
}
return 0;
}