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

HDU 4424 Conquer a New Region【贪心+并查集】

2017-06-28 20:21 316 查看
题目链接

题意:给一棵树,从一个点到另一个点的费用是路径上所有边的费用的最小值。找一个点,使它到其他n-1个点的费用和最大。

要使费用最大,就要使经过权值大的边的路径尽可能多,因此按边的权值从大到小排序,判断是哪个点到哪个点的增益最大,用并查集连在一起,最后输出整个的费用就行。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 200000 + 10;
#define ll long long

int par[maxn];
int num[maxn];
ll sum[maxn];
int N;

struct Edge
{
int u, v;
ll cost;
} edge[maxn];

bool cmp(Edge a, Edge b)
{
return a.cost > b.cost;
}

void init(int n)
{
for (int i = 1; i <= n; i++)
{
par[i] = i;
num[i] = 1;
sum[i] = 0;
}
}

int find(int x)
{
if (x == par[x])	return x;
else	return par[x] = find(par[x]);
}

void join(int x, int y, ll w)
{
x = find(x);
y = find(y);
if (x == y)	return;
ll a = sum[x] + num[y] * w;
ll b = sum[y] + num[x] * w;
if (a > b)
{
par[y] = x;
sum[x] += num[y] * w;
num[x] += num[y];
}
else
{
par[x] = y;
sum[y] += num[x] * w;
num[y] += num[x];
}
}

int main()
{
while (scanf("%d", &N) != EOF)
{
init(N);
for (int i = 1; i <= N - 1; i++)
scanf("%d %d %lld", &edge[i].u, &edge[i].v, &edge[i].cost);
sort(edge + 1, edge + N, cmp);
for (int i = 1; i <= N - 1; i++)
join(edge[i].u, edge[i].v, edge[i].cost);
printf("%lld\n", sum[find(1)]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM