Hack:
7 4 4
1 2
2 3
4 5
6 7
正解:4
输出:3
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#define N 20037
using namespace std;
int n, m, k;
int x, y, z, fa[N];
priority_queue <int> q, p;
inline int find(int x) {
if(x == fa[x]) return x;
else return fa[x] = find(fa[x]);
}
int cnt, a[N], f[N];
int main() {
scanf("%d%d%d", &n, &m, &k);
for(int i=1;i<=n;++i) fa[i] = i;
if(m == 0) { // 判0
putchar('0');
return 0;
} else if(k==0 && n>=m) { // 面向数据编程
printf("%d\n", m);
return 0;
}
for(int i=1;i<=k;++i) {
scanf("%d%d", &x, &y);
fa[find(x)] = find(y);
} // 每个块,压入大根堆
for(int i=1;i<=n;++i) ++ f[find(i)];
for(int i=1;i<=n;++i) {
if(f[i]) q.push(f[i]), cnt=i;
}
if(q.size() == 1) { // 面向数据编程
printf("%d\n", f[cnt]-m<m ? f[cnt]-m : 0);
return 0;
}
int tag = m, minn = 0x3fffffff, u;
int num = 0;
while(q.size()) {
u = q.top();
if(u <= m - num) {
num += u;
minn = min(minn, m - num);
} else p.push(-(num+u-m));
q.pop();
}
int ans = minn<=-p.top() ? m-minn : m-p.top();
printf("%d\n", ans);
return 0;
}
/*
10 4 9
8 2
1 5
5 10
9 7
10 3
3 4
4 6
8 9
6 8
: 0
7 4 4
1 2
2 3
4 5
6 7
: 4
*/