题意:有一棵树,树上任意亮点容量的定义是路径上的最小边的大小,然后要选定一个中心,问最多货物能运送多少
解法:由于是最小边再进行限制,那么我们就要使得当前最小边最大,然后用并查集维护两个点之间的中心所在位置
当两个子树进行合并的时候,选择当前能够流通货物最多的一侧作为中心就可以了
注意要使用I64d啊 原来这个还会导致TLE
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL __int64
#define maxn 222222
struct edge{
int u,v;
LL w;
}e[maxn];
bool cmp(edge x,edge y){return x.w>y.w;}
int n,f[maxn],co[maxn];
LL va[maxn];
int scan()
{
int res=0,ch;
while(!((ch= getchar())>='0'&&ch<='9')){
if(ch==EOF)return 1<<30;
}
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+(ch-'0');
return res;
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
int main(){
while(~scanf("%d",&n)){
LL ans=0;
for(int i=0;i<n-1;++i){
e[i].u=scan();e[i].v=scan();
scanf("%I64d",&e[i].w);
}
for(int i=1;i<=n;++i){co[i]=1;va[i]=0;f[i]=i;}
sort(e,e+n-1,cmp);
int x,y;
for(int i=0;i<n-1;++i){
x=find(e[i].u);y=find(e[i].v);
LL tmpu=co[x]*e[i].w+va[y];
LL tmpv=co[y]*e[i].w+va[x];
ans=max(tmpu,tmpv);
if(tmpu>tmpv){
va[x]=tmpu;
co[x]+=co[y];
f[y]=x;
}else {
va[y]=tmpv;
co[y]+=co[x];
f[x]=y;
}
}
printf("%I64d\n",ans);
}
return 0;
}