您的位置:首页 > 产品设计 > UI/UE

HDU 4424 Conquer a New Region

2013-10-17 16:17 267 查看
分析:这题已知的是一棵树,一开始可能会往树DP那块想,但发现点与点如果用状态转移,复杂度会很高,并且需要求出流量,但仔细一想会知道求任意两点间最小的边,可以用并查集思想来求,这样就能迎刃而解。只要将边从大到小排序即可。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 205000;
int pa[maxn],cnt[maxn];
long long sum[maxn];
struct Node{
int u,v,w;
}e[maxn];
bool cmp(Node a,Node b){
return a.w>b.w;
}
void init(int n){
for(int i=1;i<=n;i++){
pa[i]=i;
cnt[i]=1;
sum[i]=0;
}
}
int Find(int x){
if(x!=pa[x]){
pa[x]=Find(pa[x]);
}
return pa[x];
}
void Union(int a,int b,int w){
pa[b]=a;
sum[a]+=cnt[b]*w;
cnt[a]+=cnt[b];
}
int main(){
int n;
while(~scanf("%d",&n)){
init(n);
for(int i=0;i<n-1;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
e[i].u=a;
e[i].v=b;
e[i].w=c;
}
sort(e,e+n-1,cmp);
for(int i=0;i<n-1;i++){
//printf("%d\n",e[i].w);
int u=Find(e[i].u);
int v=Find(e[i].v);
long long tmp1=sum[u]+cnt[v]*e[i].w;
long long tmp2=sum[v]+cnt[u]*e[i].w;
if(tmp1>tmp2) Union(u,v,e[i].w);
else Union(v,u,e[i].w);
}
printf("%I64d\n",sum[Find(1)]);
}
}
/*
4
1 2 6
2 3 2
3 4 4
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: