hdu 4424 Conquer a New Region

2014-11-23 23:11:51 · 作者: · 浏览: 4
贪心+并查集。题目要求所有点到最一点经过的最小边之和最大。则有,对于两个集合A,B,也就是原树两颗子树,加上一条边使他们连通,有两种连接方案:1、使用A集合中的点作为center,则B集合中的点到center必经过新加入的边。1、使用B集合的点作为center,同理。这样的话我们就想到使新加入的边作为当前所有边的最小边,这样的话就容易计算和比较多了,于是问题就迎刃而解了:先加大边,然后并查集求值。
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#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[N], hav[N];LL val[N];  
  
struct Edge  
{  
    int u, v;LL c;  
    bool operator < (const Edge& rhs) const  
    {  
        return c > rhs.c;  
    }  
}E[N];  
  
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[n] = 1;fa[n] = 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)]); } }