杭电1856——并差集

杭电1856——并差集

原题传送门,并差集的简单介绍,大佬并差集详解。
解题思路:
这个算并差集的裸题吧。先将输入的数据(还没有连接的数据)全部用meg函数连起来,然后用fin函数遍历每个男孩最上面的父亲,用ans数组记录最上面的父亲出现的次数(ans[i]=9:i是几个人的父亲);然后遍历ans数组,找出最大的值就是答案。

注意:
1、fin函数有很多种写法,这里我建议用路径压缩,没用路径压缩的,还没试过,不知道能不能ac。
2、数据上限是10^7,如果开三个1e7的数组会爆空间的,因此,我只开了两个数组:id,记录父亲(这个是必须的);ans,记录父亲出现的次数。

ac代码

# include 
# include 
# include 
# include 
# include 
# include 
# include 
using namespace std;

const int maxn = 1e7 + 5;
int id[maxn];
int ans[maxn];

int fin(int x) {
	return id[x] = id[x] == x ? x : fin(id[x]);
}
void meg(int x, int y) {
	int a = fin(x);
	int b = fin(y);
	if (a < b) {
		id[a] = b;
	}
	else {
		id[b] = a;
	}
}
bool same(int x, int y) {
	return fin(x) == fin(y);
}

int main() {
	ios::sync_with_stdio(false);
	//freopen("mainin.txt", "r", stdin);
	int n;
	while (cin >> n) {
		for (int i = 0; i < maxn; i++) {
			id[i] = i;
		}
		memset(ans, 0, sizeof(ans));

		while (n--) {
			int a, b;
			cin >> a >> b;
			if (!same(a, b)) {
				meg(a, b);
			}
		}
		for (int i = 0; i < maxn; i++) {
			ans[fin(i)]++;
		}
		int mx = -1;
		for (int i = 0; i < maxn; i++) {
			mx = mx > ans[i] ? mx : ans[i];
		}
		cout << mx << endl;;
	}
	return 0;
}

你可能感兴趣的:(并差集,HDU,OJ)