多重匹配+输出方案
套路题
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int n,k,s,m;
int a,b,c;
const int N = 5000;
int h[N<<1],ecnt=1,head[N<<1];
struct Edge {
int nxt,to,val;
} e[1000*1000+3000];
void add(int bg,int ed,int val) {
e[++ecnt].nxt=head[bg];
e[ecnt].to=ed;
e[ecnt].val=val;
head[bg]=ecnt;
}
bool bfs() {
memset(h,-1,sizeof h);
queue<int>q;
q.push(0);
h[0]=0;
while(!q.empty()) {
int u=q.front();
q.pop();
for(int i=head[u]; i; i=e[i].nxt) {
int v=e[i].to;
if(h[v]==-1&&e[i].val) {
h[v]=h[u]+1;
q.push(v);
}
}
}
return h[4999]!=-1;
}
int dfs(int x,int f) {
if(x==4999)return f;
int used=0,tp;
for(int i=head[x]; i; i=e[i].nxt) {
int v=e[i].to;
if(h[v]-1==h[x]&&e[i].val) {
tp=dfs(v,min(e[i].val,f-used));
used+=tp;
e[i].val-=tp;
e[i^1].val+=tp;
if(used==f)return f;
}
}
if(used==0)h[x]=-1;
return used;
}
int maxflow;
void dinic() {
maxflow=0;
while(bfs()) {
maxflow+=dfs(0,0x7f7f7f7f);
}
}
int main() {
cin>>k>>n;
for(int i=1; i<=k; i++) {
scanf("%d",&a);
m+=a;
add(0,i,a);
add(i,0,0);
}
for(int i=1; i<=n; i++) {
scanf("%d",&a);
for(int j=1; j<=a; j++) {
scanf("%d",&b);
add(b,i+m,1);
add(i+m,b,0);
}
add(i+m,4999,1);
add(4999,i+m,0);
}
dinic();
if(maxflow==m)
for(int l=1; l<=k; l++) {
cout<<l<<": ";
for(int i=head[l]; i; i=e[i].nxt) {
if(e[i].val==0&&e[i].to!=0) {
cout<<e[i].to-m<<' ';
}
}
cout<<endl;
}
else cout<<"No Solution!";return 0;
}