Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 353    Accepted Submission(s): 134
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define maxn 109
#define inf 0x3f3f3f3f
using namespace std;
int par[maxn], ranks[maxn];
void init_bcj(int n) {
	for (int i = 0; i <= n; i++) {
		par[i] = i;
		ranks[i] = 0;
	}
}
int find_bcj(int x) {
	if (par[x] == x) return x;
	else {
		return par[x] = find_bcj(par[x]);
	}
}
bool unite(int x, int y) {
	x = find_bcj(x);
	y = find_bcj(y);
	if (x == y) return 0;
	if (ranks[x] < ranks[y]) {
		par[x] = y;
	}
	else {
		par[y] = x;
		if (ranks[x] == ranks[y]) ranks[x]++;
	}
	return 1;
}
bool issame_bcj(int x, int y) {
	return find_bcj(x) == find_bcj(y);
}
int t, n, m;
int ans[maxn];
struct node_edge
{
	int u, v, w;
	char c;
}e[maxn];
bool cmp(const node_edge &a, const node_edge &b) {
	return a.w < b.w;
}
struct que
{
	int a[maxn];
	int count = 0;
};
void Kruskal(char fb) {
	init_bcj(n);
	que q;
	int sum = 0,anst;
	for (int i = 1; i <= m; i++) {
		if (e[i].c != fb) {
			if (!unite(e[i].u, e[i].v)) {
				q.a[q.count] = e[i].w; q.count++;
			}
			else sum += e[i].w;
		}
		else {
			q.a[q.count] = e[i].w; q.count++;
		}
	}
	anst = m - q.count;
	if (anst < n - 1) return;
	ans[anst] = min(sum,ans[anst]);
	for (int i = 0; i < q.count; i++) {
		anst++;
		sum += q.a[i];
		ans[anst] = min(ans[anst], sum);
	}
}
int main() {
	fio;
	cin >> t;
	for (int i = 1; i <= t; i++) {
		memset(ans, inf, sizeof ans);
		cin >> n >> m;
		for (int i = 1; i <= m; i++) {
			cin >> e[i].u >> e[i].v >> e[i].w >> e[i].c;
		}
		sort(e + 1, e + 1 + m, cmp);
		Kruskal(‘B‘);
		Kruskal(‘R‘);
		cout << "Case #"<<i<<":\n";
		for (int i = 1; i <= m; i++) {
			if (ans[i] == inf) cout << "-1" << endl;
			else cout << ans[i] << endl;
		}
	}
	return 0;
}
原文:https://www.cnblogs.com/the-way-of-cas/p/9457060.html