ZOJ 3659 题解
来源:互联网 发布:怎么让淘宝信誉高起来 编辑:程序博客网 时间:2024/06/06 09:23
转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526 by---cxlove
题目:给出一棵树,找出一个点,求出所有点到这个点的权值和最大,权值为路径上所有边权的最小值。
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3659
比赛的时候卡了,一直往DP上想。
结果并查集搞定。
按边排序,从大到小插入,每条边将两个集合连起来,而新加的边是两个集合所有边最小的,那么两个集合中的点交叉的通路最小的边就是新加的,那只要枚举两个集合,a,b是a并入b更优还是b并入a更优就行了。集合内部点已经计算出,相互的只要知道集合中元素的个数就好了。
所以并查集只需要维护一个集合的元素个数,一个集合的总权值
#include<cstdio> #include<cstring> #include<algorithm> #define N 200100 using namespace std; struct Edge{ int u,v,w; }edge[N]; int f[N],num[N]; long long cost[N]; int find(int u){ if(f[u]==u)return u; return f[u]=find(f[u]); } bool cmp(struct Edge a,struct Edge b){ return a.w>b.w; } int main(){ int n,i; while(scanf("%d",&n)==1){ for(i=1;i<n;i++) scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w); sort(edge+1,edge+n,cmp); for(i=1;i<=n;i++)f[i]=i,num[i]=1,cost[i]=0; for(i=1;i<n;i++){ int uu=find(edge[i].u); int vv=find(edge[i].v); if(uu!=vv){ cost[vv]=max((long long)num[uu]*edge[i].w+cost[vv],(long long)num[vv]*edge[i].w+cost[uu]); num[vv]+=num[uu]; f[uu]=vv; } } printf("%lld\n",cost[find(1)]); } }
0 0
- ZOJ 3659 题解
- ZOJ题解
- zoj 1387 译题+题解
- zoj 1438 - Asteroids! 题解
- zoj--1089--Lotto题解
- ZOJ 3364题解
- ZOJ 3369题解
- ZOJ 3551 Bloodsucker 题解
- ZOJ 2923 题解
- ZOJ 1909Square 题解
- zoj 2050 -Flip Game题解
- zoj 3725 Painting Storages 题解
- ZOJ Monthly, August 2012 题解
- ZOJ 3057 Beans Game题解
- ZOJ 3958 Cooking Competition 题解
- ZOJ-1002 Fire Net 火力网 题解
- ZOJ月赛部分题解题报告
- POJ 1974和ZOJ 2499题解
- maven构建android项目问题备忘
- UVA - 10340 - All in All (字符串处理!)
- NYOJ 353
- [leetcode] Rotate List
- NYOJ 488
- ZOJ 3659 题解
- Linux ln命令 - 建立文件/目录链接
- HDU 5000 clone 动态规划
- NYOJ 491
- Java设计模式
- “spinner”螺旋控件
- Maven搭建SpringWebService(2)-服务端service方法改写
- NYOJ 499
- Visual Studio 6.0~2013 各版本编译器下载汇总