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 }
0 0
- hdu 4424
- HDU 4424
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- 使用OTR进行加密聊天(适用于Gtalk、Facebook聊天室)
- hdu 3047(带权并查集)
- hdu 2818(带权并查集)
- hdu 4263(有限制的生成树)
- hdu 4253(二分+最小生成树)
- hdu 4424
- 并查集小结
- hdu 2065(递推+矩阵乘法)
- hdu 4179(有限制的最短路)
- MVC访问Oracle数据库示例
- hdu 3360(最小覆盖)
- hdu 3118(二进制枚举)
- hdu 2389(最大匹配bfs版)
- hdu 1669(二分+多重匹配)