您的位置:首页 > 其它

HDU-4313 Matrix 最小生成树,集合划分

2012-07-27 02:37 417 查看
该题就是考的是如何花最小的代价使得一棵树划分开且不含后同类节点。

我们将边按从大到小的顺序排好序,然后就是看是否这条边能够使得两个同类的节点连在一起,如果能够的话,那么这条边就是我们要选择的划分边。首先将特征值保留起来,并通过并查集扩充给标记点。

代码如下:

#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;

int N, M, set[100005], have[100005];

struct Edge
{
int x, y, fee;
bool operator < (Edge t) const
{
return fee > t.fee;
}
}e[100005];

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

void merge(int a, int b)
{
set[a] = b;
if (have[a]) {
have[b] = 1;
}
}

int main()
{
int T, a, b, c;
long long int sum;
scanf("%d", &T);
while (T--) {
sum = 0;
memset(have, 0, sizeof (have));
map<int,int>mp;
scanf("%d %d", &N, &M);
set[N-1] = N-1;
for (int i = 0; i < N-1; ++i) {
scanf("%d %d %d", &e[i].x, &e[i].y, &e[i].fee);
set[i] = i;
}
for (int i = 0; i < M; ++i) {
scanf("%d", &c);
have[c] = 1;
}
sort(e, e + N - 1);
for (int i = 0; i < N-1; ++i) {
int a = find(e[i].x), b = find(e[i].y);
if (have[a] && have[b]) {
sum += e[i].fee;
continue;
}
merge(a, b);
}
printf("%I64d\n", sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: