papamelon 245. 徵募 Conscription(挑戰程序設計競賽)

地址 https://www.papamelon.com/problem/245

需要徵募女兵 N 人,男兵 M 人。
每徵募一個人需要花費 10000 人民幣。如果兩個人之間有某種關係,則可以少花錢。

例如,一男一女之間的關係值爲 d,其中一人已經被徵募,當我們再徵募第二個人時,花費爲 10000−d 元。

多人之間可以形成環狀關係,來看一個例子:
A 和 B 有關係,可減免 100 元
B 和 C 有關係,可減免 200 元
C 和 A 有關係,可減免 300 元
招募 A 花費 10000 元
招募 B,因爲有 A,減免 100 元,花費 10000−100 元
招募 C,因爲有 B,減免 
200 元,花費 10000−200 元
儘管 C 和 A 之間有關係,但 A,B,C 都招進來了,無法再減免,總花費是 
30000−300 元
以上只是一種招人方案,並不一定是最省錢的
現在給出所有的關係信息,讓我們徵募到 
N 女 M 男,求最小花費。

輸入
第一行整數 T(1≤T≤10),表示有多少組測試數據
每組測試數據最開始先是一個空行,再接着以下的部分:
第一行有 3 個整數 
N 和 M 和 R
接下來的 R 行,每行均表示一條人際關係,三個整數 
x,y,d, 表示女兵 x 和男兵 y 的關係值爲 d
1≤N,M≤10000
1≤R≤50000
0<d<10000
0≤x<N
0≤y<M
輸出T 行,每行一個整數,表示該組測試數據中所需的最小費用
樣例 1
輸入
2

5 5 8
4 3 6831
1 3 4583
0 0 6592
0 1 3063
3 3 4975
1 3 2049
4 2 2104
2 2 781

5 5 10
2 4 9820
3 2 6236
3 1 8864
2 4 8326
2 0 5156
2 0 1463
4 1 2439
0 4 4373
3 4 8889
2 4 3133
輸出
71071
54223

解答


#include <iostream>
#include <algorithm>
#include <memory.h>

using namespace std;

const int N = 200010, M = 500010;
struct Edge {
	int a, b, w;
	bool operator<(const Edge& e) {
		return w >  e.w;
	}
}edges[M];

int f[N];
int t, m, n, r;

int find(int x) {
	if (f[x] != x) f[x] = find(f[x]);

	return f[x];
}



int kruskal() {
	sort(edges, edges + r);
    cout <<edges[0].w <<" "<<edges[1].w<<endl;
	for (int i = 0; i <= m + n; i++) f[i] = i;
	int res = 0;
	for (int i = 0; i < r; i++) {
		int a = edges[i].a, b = edges[i].b, w = edges[i].w;
		a = find(a); b = find(b);
		if (a != b) {
			f[a] = b;
			res += w;
		}
	}

	return res;
}



int main() {
	cin >> t;
	while (t--) {
		cin >> n >> m >> r;
		memset(edges, 0, sizeof edges);
		for (int i = 0; i < r; i++) {
			int a, b, w; cin >> a >> b >> w;
			edges[i].a = a; edges[i].b = b+n; edges[i].w = w;
		}

		int t = kruskal();

		cout << 10000 * (m + n) - t << endl;
	}

	return 0;
}

我的視頻題解空間

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章