看到选人要选一整串就想到了dfs求连通块中有多少个人再对其进行逐一枚举使其尽可能接近答案求得最优解(二分?)。
以下为27pts代码,好玩之处就在于开大了要T,开小了要RE,并且MLE和RE同时存在,姹紫嫣红 and
改良版37pts五彩缤纷
......
求救 QAQ
#include<bits/stdc++.h>
#define ll int
using namespace std;
struct Edge{
ll next,to;
}edge[30055];
ll n,m,k,tim,head[30055],cnt,be[30055],ans,suit=1e9,sum[30055],kk;
bool vis[30055];
void add(ll from,ll to){
edge[cnt].next=head[from];
edge[cnt].to=to;
head[from]=cnt++;
return ;
}
void dfs(ll x,ll fa){
if(vis[x]==0)
sum[kk]++;
vis[x]=1;
//cout<<x<<"\n";
for(int i=head[x];~i;i=edge[i].next){
if(edge[i].to==fa)
continue;
dfs(edge[i].to,x);
}
return ;
}
bool cmp(ll a,ll b){
return a>b;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>k;
memset(head,-1,sizeof(head));
for(int i=1;i<=k;i++){
ll a,b;
cin>>a>>b;
add(a,b);
add(b,a);
vis[a]=1;
vis[b]=1;
}
for(int i=1;i<=n;i++){
if(vis[i]==0)
tim++;
}
memset(vis,0,sizeof(vis));
//cout<<tim<<"\n";
for(int i=1;i<=n;i++){
if(vis[i]==0){
//cout<<"begin:"<<i<<"\n";
kk++;
dfs(i,0);
}
}
sort(sum+1,sum+kk+1,cmp);
for(int i=1;i<=kk;i++){
ans+=sum[i];
//cout<<"i:"<<i<<" ans:"<<ans<<" suit:"<<suit<<" sum[i]:"<<sum[i]<<"\n";
if(ans<m){
if((m-ans)<=tim){
cout<<m;
return 0;
}
else{
if(abs(m-ans)<abs(m-suit)){
suit=ans;
//cout<<"cnm:"<<abs(m-ans)<<" "<<suit<<"\n";
}
}
}
else if(ans==m){
cout<<m;
return 0;
}
else{
if(abs(m-ans)<abs(m-suit)){
suit=ans;
//cout<<"cnm:"<<abs(m-ans)<<" "<<suit<<"\n";
}
}
}
cout<<suit;
return 0;
}