![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; int k,n; int tot=-1,h[3005],ans=0,sum=0; struct node{ int from,next,to,rest,full; }e[100005]; void add(int x,int y,int z){ tot++; e[tot].next=h[x]; h[x]=tot; e[tot].from=x; e[tot].to=y; e[tot].rest=z; e[tot].full=z; } int dis[3005],g[3005],flow[3005]; bool vis[3005]; int bfs(int s,int t){ queue<int>q; dis[s]=0; q.push(s);vis[s]=true; while(!q.empty()){ int u=q.front();vis[u]=false;q.pop(); for(int i=h[u];i!=(-1);i=e[i].next){ if(dis[e[i].to]>dis[u]+1&&g[e[i].to]==(-1)&&e[i].rest>0){ g[e[i].to]=i; flow[e[i].to]=min(flow[u],e[i].rest); dis[e[i].to]=dis[u]+1; if(vis[e[i].to]==false){ vis[e[i].to]=true; q.push(e[i].to); } } } } } int EK(int s,int t){ while(1){ memset(vis,false,sizeof(vis)); memset(dis,0x7f,sizeof(dis)); memset(flow,0x7f,sizeof(flow)); memset(g,-1,sizeof(g)); bfs(s,t); if(g[t]==(-1))return 0; ans+=flow[t]; for(int p=t;p!=(s);p=e[g[p]].from){ e[g[p]].rest-=flow[t]; e[g[p]^1].rest+=flow[t]; } } } int main(){ memset(h,-1,sizeof(h)); cin>>k>>n; for(int i=1;i<=k;i++){ int x;cin>>x;sum+=x; add(0,i,x); add(i,0,0); } for(int i=1;i<=n;i++){ int num,x;cin>>num; add(i+k,n+k+1,1); add(n+k+1,i+k,0); for(int j=1;j<=num;j++){ cin>>x; add(x,i+k,1); add(i+k,x,0); } } EK(0,n+k+1); if(sum==ans){ for(int i=1;i<=k;i++){cout<<i<<":"; for(int j=h[i];j!=(-1);j=e[j].next){ if(e[j].rest==0&&e[j].to!=0){ cout<<" "<<e[j].to-k; } } cout<<endl; } } else{ cout<<"No Solution!"<<endl; exit(0); } }
水题