洛谷传送门
LOJ传送门
解析:
每个点拆一下从出点和入点做二分图匹配,同时记录一下二分图匹配到的另一部分的节点,然后跳一下就行了
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
cs int N=153;
bool g[N][N];
int vis[N],idx=1;
int match[N],to[N];
int n;
bool find(int u){
for(int re v=1;v<=n;++v){
if(g[u][v]&&(vis[v]^idx)){
vis[v]=idx;
if(!match[v]||find(match[v])){
match[v]=u;to[u]=v;
return true;
}
}
}
return false;
}
int m;
signed main(){
n=getint();
m=getint();
for(int re i=1;i<=m;++i){
int u=getint(),v=getint();
g[u][v]=true;
}
for(int re i=1;i<=n;++i,++idx)find(i);
int cnt=0;++idx;
for(int re i=1;i<=n;++i){
int u=i;
if(!match[u]){
printf("%d ",u);
vis[u]=idx;
while(to[u]){
u=to[u];
vis[u]=idx;
printf("%d ",u);
}
pc('\n');
++cnt;
}
}
cout<<cnt<<"\n";
return 0;
}