​传送门​

第i轮向妙计建边 , 然后跑最大匹配

发现第i个找不到的时候就可以break 然后输出答案了


#include<bits/stdc++.h>
#define N 1050
#define M 100050
using namespace std;
int first[N],next[M],to[M],tot;
int n,m,vis[N],match[N],cnt,ans[N];
void add(int x,int y){
next[++tot]=first[x],first[x]=tot,to[tot]=y;
}
bool find(int u){
for(int i=first[u];i;i=next[i]){
int t=to[i]; if(!vis[t]){
vis[t]=1;
if(!match[t] || find(match[t])){
match[t]=u; return true;
}
}
}return false;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y; scanf("%d%d",&x,&y); ++x,++y;
add(i,x) , add(i,y);
}
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
if(!find(i)) break; cnt++;
}
for(int i=1;i<=n;i++) ans[match[i]]=i;
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++) printf("%d\n",ans[i]-1);
return 0;
}