代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=5e5+10;
const int inf=1e9+7;
int n,m,k,ans,fa[maxn],dp[maxn],sum=0,num[maxn]; //dp[j] 表示从选j个学霸
inline int read() {
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-')w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
inline void write(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void init() {
for(int i=1;i<=n;++i)
fa[i]=i,num[i]=1;
}
inline int find(int u) {
if(fa[u]==u) return fa[u];
int tmp=find(fa[u]);
num[u]+=num[fa[u]];
return fa[u]=tmp;
}
inline void merge(int u,int v) {
int fu=find(u),fv=find(v);
if(fu!=fv) {
fa[fu]=fv;
num[fv]+=num[fu];
num[fu]=0;
}
}
signed main() {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read(),m=read(),k=read();
init();
for(int i=1;i<=k;++i) {
int a=read(),b=read();//if(a>b) swap(a,b);
merge(a,b);
}
for(int i=1;i<=n;++i)
if(fa[i]==i) sum+=num[i];
dp[sum]=1,dp[0]=1;
for(int i=1;i<=n;++i) {
if(num[i]==0||fa[i]!=i) continue;
for(int j=sum;j>=0;--j) {
dp[j]=(dp[j]||dp[j-num[i]]);
}
}
for(int i=0;i<=min(m,sum-m);++i) {
if(dp[m-i]) {
write(m-i),puts("");
break;
}
else if(dp[m+i]) {
write(m+i),puts("");
break;
}
}
return 0;
}
输入数据:
10 4 9
8 2
1 5
5 10
9 7
10 3
3 4
4 6
8 9
6 8
答案输出:
0