hdu 4424

来源:互联网 发布:热血传奇闪避命中数据 编辑:程序博客网 时间:2024/05/20 18:46

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4424
题意:给你一颗树,树中每条边有一权值c,对于从i节点到j节点的路径,其权值定义为该路径上边权值的最小值,于是问找到一个中心点,使得从该点到其他节点的路径权值和最大,求该最大值。

思路;要使得权值和最大,容易想到对边进行从大到小排序,用一个sum来记录权值,cnt来记录节点个数,然后每次合并时取权值和较大的那个即可。

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 200200 7 typedef long long LL; 8 int parent[MAXN]; 9 LL sum[MAXN];10 int cnt[MAXN];11 struct Edge{12    int u,v,w;13 }edge[MAXN];14 int n;15 16 void Initiate()17 {18    memset(sum,0,(n+2)*sizeof(sum[0]));19    for(int i=0;i<=n;i++){20       parent[i]=i;21       cnt[i]=1;22    }23 }24 25 int Find(int x)26 {27    if(x==parent[x])28       return x;29    parent[x]=Find(parent[x]);30    return parent[x];31 }32 33 void Union(int r1,int r2,LL w)34 {35    parent[r1]=r2;36    cnt[r2]+=cnt[r1];37    sum[r2]+=w;38 }39 40 int cmp(const Edge &p,const Edge &q)41 {42    return p.w>q.w;43 }44 45 int main()46 {47  //  freopen("1.txt","r",stdin);48    while(~scanf("%d",&n))49    {50       Initiate();51       for(int i=0;i<n-1;i++){52          scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);53       }54       sort(edge,edge+n-1,cmp);55       for(int i=0;i<n-1;i++){56          int r1=Find(edge[i].u);57          int r2=Find(edge[i].v);58          LL w=(LL)edge[i].w;59          LL tmp1=cnt[r2]*w+sum[r1];60          LL tmp2=cnt[r1]*w+sum[r2];61          if(tmp1>tmp2){62             Union(r2,r1,tmp1-sum[r1]);63          }else64             Union(r1,r2,tmp2-sum[r2]);65       }66       printf("%I64d\n",sum[Find(1)]);67    }68    return 0;69 }
View Code

 

 

0 0
原创粉丝点击