HDU 4424 Conquer a New Region 并查集
2018-06-17 23:53:55来源:未知 阅读 ()
题意:给出n个点和n-1条边,a到b的最大承载量为a和b之间承载量的最小值。以某一点为中心,求承载量之和的最大值。
由于a和b之间的承载量为它们之间承载量的最小值,所以先以两点之间的承载量从大到小排序。每次合并时有A,B两个集合,他们之间的承载量(cost)为当前最小,如果B合并到A,则A的总承载量为A之前的总承载量加上A,B之间的承载量成衣集合B中点的个数,即 cost[A]=cost[A]+num[B]*cost.
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int inf=1000000000; const int maxn=200005; int f[maxn]; ll num[maxn],cost[maxn]; struct Branch { int a; int b; ll cost; }bra[maxn]; bool cmp(Branch a,Branch b) { return a.cost>b.cost; } int Find(int x) { if(x!=f[x]) f[x]=Find(f[x]); return f[x]; } ll Function(int n) { for(int i=0;i<n-1;i++) { int a=Find(bra[i].a); int b=Find(bra[i].b); if(cost[a]+num[b]*bra[i].cost>=cost[b]+num[a]*bra[i].cost) { f[b]=a; cost[a]+=num[b]*bra[i].cost; num[a]+=num[b]; } else { f[a]=b; cost[b]+=num[a]*bra[i].cost; num[b]+=num[a]; } } return cost[Find(1)]; } int main() { //freopen("in.txt","r",stdin); int n; while(scanf("%d",&n)!=EOF) { for(int i=0;i<=n;i++) { f[i]=i; num[i]=1; } memset(cost,0,sizeof(cost)); for(int i=0;i<n-1;i++) scanf("%d%d%I64d",&bra[i].a,&bra[i].b,&bra[i].cost); sort(bra,bra+n-1,cmp); printf("%I64d\n",Function(n)); } return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:Lexer的设计--中(4)
下一篇:Lexer的设计--上(3)
- HDU-2955-Robberies(0-1背包) 2020-03-30
- hdu1455 拼木棍(经典dfs) 2020-02-29
- anniversary party_hdu1520 2020-02-16
- hdu1062 text reverse 2020-01-27
- hdu4841 2020-01-26
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash