模板。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<time.h> 5 //#include<complex> 6 //#include<set> 7 //#include<queue> 8 #include<algorithm> 9 #include<stdlib.h> 10 using namespace std; 11 12 #define LL long long 13 int qread() 14 { 15 char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1); 16 do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f; 17 } 18 19 //Pay attention to '-' , LL and double of qread!!!! 20 21 int n,m; 22 #define maxn 511 23 #define maxm 15011 24 struct Edge{int to,next,flow,cap;}; 25 struct Network 26 { 27 Edge edge[maxm]; int first[maxn],le,n; 28 void clear(int N) {le=2; memset(first,0,sizeof(first)); n=N;} 29 void in(int x,int y,int cap) {Edge &e=edge[le]; e.to=y; e.cap=cap; e.flow=0; e.next=first[x]; first[x]=le++;} 30 void insert(int x,int y,int cap) {in(x,y,cap); in(y,x,0);} 31 int dis[maxn]; int que[maxn],cur[maxn],head,tail,s,t; 32 bool bfs() 33 { 34 memset(dis,0,sizeof(dis)); dis[s]=1; 35 head=tail=0; que[tail++]=s; 36 while (head!=tail) 37 { 38 int x=que[head++]; 39 for (int i=first[x];i;i=edge[i].next) 40 { 41 Edge &e=edge[i]; 42 if (!dis[e.to] && e.cap>e.flow) 43 { 44 dis[e.to]=dis[x]+1; 45 que[tail++]=e.to; 46 } 47 } 48 } 49 return dis[t]; 50 } 51 int dfs(int x,int a) 52 { 53 if (x==t || !a) return a; 54 int flow=0,f; 55 for (int &i=cur[x];i;i=edge[i].next) 56 { 57 Edge &e=edge[i]; 58 if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(e.cap-e.flow,a)))>0) 59 { 60 flow+=f; e.flow+=f; 61 edge[i^1].flow-=f; a-=f; 62 if (!a) break; 63 } 64 } 65 return flow; 66 } 67 int Dinic(int S,int T) 68 { 69 s=S; t=T; 70 int ans=0; 71 while (bfs()) 72 { 73 for (int i=1;i<=n;i++) cur[i]=first[i]; 74 ans+=dfs(s,0x3f3f3f3f); 75 } 76 return ans; 77 } 78 }g; 79 80 bool vis[maxn]; 81 int main() 82 { 83 n=qread(); m=qread(); 84 int s=2*n+1,t=s+1; g.clear(t); 85 for (int i=1,x,y;i<=m;i++) 86 { 87 x=qread(); y=qread(); 88 g.insert(x,y+n,1); 89 } 90 for (int i=1;i<=n;i++) g.insert(s,i,1),g.insert(i+n,t,1); 91 int ans=n-g.Dinic(s,t); 92 for (int i=1;i<=n;i++) if (!vis[i]) 93 { 94 printf("%d",i); 95 bool flag=1; int x=i; 96 while (flag) 97 { 98 vis[x]=1; 99 flag=0; 100 for (int j=g.first[x];j;j=g.edge[j].next) 101 { 102 Edge &e=g.edge[j]; if (e.to==s) continue; 103 if (e.cap==e.flow) {flag=1; printf(" %d",x=e.to-n); break;} 104 } 105 } 106 puts(""); 107 } 108 printf("%d\n",ans); 109 return 0; 110 }