poj3723(最大生成树)

原创 2016年08月29日 20:11:02

题目:点击打开链接

/*
translation:
	需要征兵女兵n人,男兵m人。征募每个人需要1w元,如果女兵x和男兵y有亲密度d。则一旦军队
	中有任意一方,则征募另外一方就可以减少d的费用。现在给出男女人数以及他们之间的亲密度,
	求征募完成所需的最少费用。

solution:
	kruskal,最大生成树。
	该题可以抽象成一个最大生成树模型。将每条边边值取负,就可求最小生成树了。之后将最小生成树的
	权值加上10000*(m+n),既是所求的答案!

note:
    并查集合并操作一定是将根合并的,一不留神容易写错。

date:
	2016.8.29
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>

using namespace std;
const int maxn = 20001;

struct Edge {
	int from, to, d;
	Edge(int f_, int t_, int d_) : from(f_), to(t_), d(d_) {}
	bool operator < (const Edge &rhs) const {
		return d < rhs.d;	//从小到大
	}
};

int n, m, r;	//n girls, m boys, r relations
int pa[maxn];
vector<Edge> edges;

int get_root(int a) {
	if(pa[a] == a)	return a;
	pa[a] = get_root(pa[a]);
	return pa[a];
}

void Merge(int i, int j) {
	int r1 = get_root(i);
	int r2 = get_root(j);

	if(r1 == r2)	return;
	pa[r2] = r1;
}

int main()
{
    //freopen("in.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while(T--) {
		edges.clear();
		scanf("%d%d%d", &n, &m, &r);
		int x, y, d;
		for(int i = 0; i < r; i++) {
			scanf("%d%d%d", &x, &y, &d);
			edges.push_back(Edge(x, y + n, -d));
		}

		sort(edges.begin(), edges.end());

		//kruskal
		for(int i = 0; i < n + m; i++)	pa[i] = i;
		int res = 0;
		for(int i = 0; i < r; i++) {
			Edge e = edges[i];
			if(get_root(e.from) != get_root(e.to)) {
				Merge(e.from, e.to);
				res += e.d;
			}
		}

		int ans = 10000 * (n+m) + res;
		printf("%d\n", ans);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

POJ 3723 Conscription【最大生成树】

Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10608   ...

POJ--3723---Conscription---最大生成树

本题大体题意是:一个国王要招募士兵,现有男兵和女兵,招募一个需要10000元,但是如果一个男兵和一个女兵有关系d的话,在已经招募一个的情况下招募另一个只需花费10000-d即可。现在给出以下关系,问国...

POJ 3723 Conscription 最大生成树 + 并查集

看了挑战上的这道题,一开始根本没反应过来这就是最大生成树。不过仔细想想,如果我们把是朋友或者间接是朋友的人都放在一个集合,那么但我们通过a来招募b的时候,就在a和b中间连一条边,权值就是a和b的亲密度...

POJ 3723 conscription 最大生成树

F - Conscription Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Subm...

POJ - 3723 Conscription(最大生成树Kruskal)

点击打开题目链接 Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13061...

POJ3723Conscription (最大生成树之Kruskal)

Problem Description Windy has a country, and he wants to build an army to protect his country. ...

POJ 3723 Conscription(最大生成树)

POJ 3723 Conscription(最大生成树) http://poj.org/problem?id=3723 题意: 要招n女,m男,每招一个人需要10000元,但是有一些男女有关系,代价为...

POJ 3723 Conscription 【最大生成树||最大权森林】

传送门:POJ 3723 Conscription 描述: Conscription Time Limit: 1000MS   Memory Limit: 65536...

poj3723 Conscription Kruscal算法最大生成森林

Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9902   A...

poj3723 Conscription无向图最大权森林问题

1.题目原文 题目链接:http://poj.org/problem?id=3723 Language: Default Conscription Time Limit: 1000M...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj3723(最大生成树)
举报原因:
原因补充:

(最多只允许输入30个字)