题目链接:

https://codeforces.com/problemset/problem/1609/D

题目大意:

\(n\) 个人参与会议,他们相互之间不认识,\(William\)\(d\) 条介绍关系,每条关系就是让参加会议的 \(x\)\(y\) 这两个人相互认识,输出 \(Willian\) 每介绍一条关系后参加会议的一个人最多能认识多少人。

思路:

建立两个人的关系,可以想到并查集,将两者建立联系,然后更新两个人的数量。
但是还有一种情况,如果 \(William\) 介绍的两个人已经认识了,那就意味着这个关系已经没用了,我们可以任意指定两个人相互认识(题目中好像没说,或者我没读明白题目 \(qwq\),我是从官方题解里面悟出来的)。
在这种情况下,我们需要统计可以任意指定的次数,然后为了使一个人认识最多人,那么我们就要选择认识人数多的那几个人互相认识,这样子才会使结果最大。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int fa[N], x, y, n, d, p = 1, num[N], t[N];
int find(int k){
	if (k != fa[k]) fa[k] = find(fa[k]);
	return fa[k];
}
void unit(int a, int b){
	int p = find(a);
	int q = find(b);
	fa[q] = p;
	num[p] += num[q];
	num[q] = 0;  //更新认识的人数
}
int main(){
	cin >> n >> d;
	for (int i = 1; i <= n; i++){
		fa[i] = i;
		num[i] = 1;
	}
	for (int i = 1; i <= d; i++){
		scanf("%d %d", &x, &y);
		if (find(x) == find(y)) p++;
		else unit(x, y);
		for (int i = 1; i <= n; i++)
			t[i] = num[i];
		sort(t + 1, t + n + 1, greater<int>() );  //从大到小排序
		int ans = t[1] - 1;  //统计一个人能认识多少人,所以自己不算在内
		for (int i = 2; i <= p; i++)
			ans += t[i];
		cout << ans << "\n";
	}
	return 0;
}
posted on 2022-01-25 09:50  Hamine  阅读(105)  评论(0编辑  收藏  举报