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

hdu 4424 Conquer a New Region

2013-09-25 11:07 344 查看
           贪心+并查集。题目要求所有点到最一点经过的最小边之和最大。则有,对于两个集合A,B,也就是原树两颗子树,加上一条边使他们连通,有两种连接方案:1、使用A集合中的点作为center,则B集合中的点到center必经过新加入的边。1、使用B集合的点作为center,同理。这样的话我们就想到使新加入的边作为当前所有边的最小边,这样的话就容易计算和比较多了,于是问题就迎刃而解了:先加大边,然后并查集求值。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;

const int N = 222222;
const int MOD = 1e9 + 7;
int fa
, hav
;LL val
;

struct Edge
{
int u, v;LL c;
bool operator < (const Edge& rhs) const
{
return c > rhs.c;
}
}E
;

int find(int x)
{
return fa[x] != x ? fa[x] = find(fa[x]) : x;
}

int main()
{
int u, v, i, j, n;LL ans;
while(scanf("%d", &n) != EOF)
{
for(i = 0; i < n - 1; i ++)
{
scanf("%d%d%I64d", &E[i].u, &E[i].v, &E[i].c);
fa[i + 1] = i + 1;
hav[i + 1] = 1;
}
hav
= 1;fa
= n;
CLR(val, 0);
sort(E, E + n - 1);
for(i = 0; i < n - 1; i ++)
{
u = find(E[i].u);
v = find(E[i].v);
if(val[u] + hav[v] * E[i].c > val[v] + hav[u] * E[i].c)
{
val[u] += hav[v] * E[i].c;
hav[u] += hav[v];
fa[v] = u;
}
else
{
val[v] += hav[u] * E[i].c;
hav[v] += hav[u];
fa[u] = v;
}
}
printf("%I64d\n", val[find(1)]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  并查集