题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4882
题意:给出一棵树,边有权值。两个节点i和j之间的距离D(i,j)定义为i和j之间的路径上最小的权值。求一个点使得该点到其他点的D值和最大?
思路:并查集:将权值按照降序插入并查集。。。一开始我以为是树形DP呢,搞了半天。。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define i64 long long
using namespace std;
struct node
{
int size,p;
i64 sum;
};
struct Node
{
int u,v;
i64 c;
};
Node b[200005];
node a[200005];
int n;
int cmp(Node a,Node b)
{
return a.c>b.c;
}
int get(int u)
{
if(a[u].p!=u) a[u].p=get(a[u].p);
return a[u].p;
}
void deal()
{
int i,u,v,ru,rv;
i64 c,x,y;
for(i=1;i<=n-1;i++)
{
u=b[i].u;
v=b[i].v;
c=b[i].c;
ru=get(u);
rv=get(v);
x=a[ru].sum+c*a[rv].size;
y=a[rv].sum+c*a[ru].size;
if(x<y)
{
a[ru].p=rv;
a[rv].size+=a[ru].size;
a[rv].sum=y;
}
else
{
a[rv].p=ru;
a[ru].size+=a[rv].size;
a[ru].sum=x;
}
}
printf("%lld\n",a[get(1)].sum);
}
int main()
{
while(scanf("%d",&n)!=-1)
{
int i;
for(i=1;i<n;i++) scanf("%d%d%lld",&b[i].u,&b[i].v,&b[i].c);
sort(b+1,b+n,cmp);
for(i=1;i<=n;i++)
{
a[i].size=1;
a[i].sum=0;
a[i].p=i;
}
deal();
}
return 0;
}