标签:题目 Network 认识 int CF fa num Social find
题目链接:
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;
}
标签:题目,Network,认识,int,CF,fa,num,Social,find 来源: https://www.cnblogs.com/Hamine/p/15841793.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。