选学霸 - 洛谷https://www.luogu.com.cn/problem/P2170
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cstring>
#include <set>
#include <cmath>
#include <map>
#include <cstdlib>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int MN = 65005;
const int MAXN = 2000010;
const int INF = 0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false)
int n, m, k;
int pre[MAXN];
int find(int x) {
if (pre[x] == x) {
return x;
}
return pre[x] = find(pre[x]);
}
bool dp[MAXN];
int cnt[MAXN];
int xueba[MAXN];
int main() {
IOS;
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
pre[i] = i;
cnt[i] = 1;
}
int x, y;
for (int i = 1; i <= k; i++) {
cin >> x >> y;
x = find(x);
y = find(y);
if (x != y) {
pre[x] = y;
cnt[y] += cnt[x];
}
}
int count = 0;
for (int i = 1; i <= n; i++) {
if (pre[i] == i) {
xueba[++count] = cnt[i];
}
}
dp[0] = true;
for (int i = 1; i <= count; i++) {
for (int j = n; j >= xueba[i]; j--) {
dp[j] |= dp[j - xueba[i]];
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
if (dp[i] && abs(ans - m) > abs(i - m)) {
ans = i;
}
}
cout << ans;
return 0;
}