Be careful to optimize with the current arc!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> const int MAXN=1e5+5; const int INF=1e9+7; int n,m; struct Edge { int nxt; int to; int f; }edge[MAXN<<1]; int num=1,sink,src; int head[MAXN]; void add(int from,int to,int f) { edge[++num].nxt=head[from]; edge [num] .to = to; edge[num].f=f; head[from]=num; edge[++num].nxt=head[to]; edge[num].to=from; edge[num].f=0; head[to]=num; } int dist[MAXN]; bool vis[MAXN]; bool bfs() { std::queue<int>q; std::memset(dist,0,sizeof(dist)); std::memset(vis,0,sizeof(vis)); q.push(src); dist[0]=0; vis[src]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=edge[i].nxt) { int v=edge[i].to; if(!vis[v]&&edge[i].f) { dist[v]=dist[u]+1; q.push(v); force[v] = 1 ; } } } return vis[sink]; } int maxflow(int x,int delta) { if(x==sink) { return delta; } int res=0; for(int i=head[x];i && delta;i=edge[i].nxt) { int v=edge[i].to; if(dist[v]==dist[x]+1&&edge[i].f) { int dd=maxflow(v,std::min(edge[i].f,delta)); res+=dd; delta-=dd; edge[i].f-=dd; edge[i^1].f+=dd; } } return res; } int ans=0; void dinic() { while(bfs()) { ans+=maxflow(src,INF); } } int q[MAXN]; void print() { for(int i=1;i<=n;i++) { q[0]=0; std::memset(q,0,sizeof(q)); for(int j=head[i];j;j=edge[j].nxt) { int v=edge[j].to; if(!edge[j].f) { q[++q[0]]=v-n; } } for(int k=q[0];k>0;k--) { printf("%d ",q[k]); } printf("\n"); } } intmain () { int sum = 0 ; std::scanf("%d%d",&n,&m); sink=n+m+1; src=0; for(int i=1;i<=n;i++) { int x; std::scanf("%d",&x); add(src,i,x); for(int j=n+1;j<=n+m;j++) { add(i,j,1); } sum+=x; } for(int i=n+1;i<=m+n;i++) { int x; std::scanf("%d",&x); add(i,sink,x); } dinic(); if(ans==sum) { printf("1\n"); print(); } else printf("0\n"); return 0; }