链接:https://www.oj.swust.edu.cn/oj/problem/show/1742
分析:裸题,直接上模板搞一下二分图匹配即可。
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 #include<stack> 5 #include<cstdio> 6 #include<cstring> 7 using namespace std; 8 const int maxn=1e3+5,INF=1e9; 9 int k,n,m=0; 10 struct Edge{ 11 int from,to,cap,flow; 12 Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){} 13 }; 14 struct ISAP{ 15 int n,s,t; 16 vector<Edge> edges; 17 vector<int> G[maxn]; 18 bool vis[maxn]; 19 int d[maxn]; 20 int cur[maxn]; 21 int p[maxn]; 22 int num[maxn]; 23 24 void init(int n){ 25 this->n=n; 26 edges.clear(); 27 for(int i=0;i<n;i++)G[i].clear(); 28 } 29 30 void AddEdge(int from,int to,int cap){ 31 edges.push_back(Edge(from,to,cap,0)); 32 edges.push_back(Edge(to,from,0,0)); 33 G[from].push_back(edges.size()-2); 34 G[to].push_back(edges.size()-1); 35 } 36 37 void BFS(){ 38 memset(vis,0,sizeof(vis)); 39 queue<int> Q; 40 Q.push(t); 41 d[t]=0; 42 vis[t]=1; 43 while(!Q.empty()){ 44 int x=Q.front();Q.pop(); 45 for(int i=0;i<G[x].size();i++){ 46 Edge &e=edges[G[x][i]^1]; 47 if(e.flow==e.cap)continue; 48 if(!vis[e.from]){ 49 vis[e.from]=1; 50 d[e.from]=d[x]+1; 51 Q.push(e.from); 52 } 53 } 54 } 55 } 56 57 int Augment(){ 58 int x=t,a=INF; 59 while(x!=s){ 60 Edge &e=edges[p[x]]; 61 a=min(a,e.cap-e.flow); 62 x=edges[p[x]].from; 63 } 64 x=t; 65 while(x!=s){ 66 edges[p[x]].flow+=a; 67 edges[p[x]^1].flow-=a; 68 x=edges[p[x]].from; 69 } 70 return a; 71 } 72 73 int Maxflow(int s,int t){ 74 this->s=s;this->t=t; 75 int flow=0; 76 BFS(); 77 memset(num,0,sizeof(num)); 78 for(int i=0;i<n;i++)num[d[i]]++; 79 int x=s; 80 memset(cur,0,sizeof(cur)); 81 while(d[s]<n){ 82 if(x==t){ 83 flow+=Augment(); 84 x=s; 85 } 86 int ok=0; 87 for(int i=cur[x];i<G[x].size();i++){ 88 Edge &e=edges[G[x][i]]; 89 if(e.cap>e.flow&&d[x]==d[e.to]+1){ 90 ok=1; 91 p[e.to]=G[x][i]; 92 cur[x]=i; 93 x=e.to; 94 break; 95 } 96 } 97 if(!ok){ 98 int m=n-1; 99 for(int i=0;i<G[x].size();i++){ 100 Edge &e=edges[G[x][i]]; 101 if(e.cap>e.flow)m=min(m,d[e.to]); 102 } 103 if(--num[d[x]]==0)break; 104 num[d[x]=m+1]++; 105 cur[x]=0; 106 if(x!=s)x=edges[p[x]].from; 107 } 108 } 109 return flow; 110 } 111 void Print(){ 112 for(int i=1;i<=k;i++){ 113 printf("%d:",i); 114 for(int j=0;j<G[i].size();j++){ 115 Edge &e=edges[G[i][j]]; 116 if(e.flow==1){ 117 printf(" %d",e.to-k); 118 } 119 } 120 printf(" "); 121 } 122 } 123 }isap; 124 int main(){ 125 // freopen("e:\in.txt","r",stdin); 126 int v,p; 127 scanf("%d%d",&k,&n); 128 isap.init(k+n+2); 129 for(int i=1;i<=k;i++){ 130 scanf("%d",&v); 131 isap.AddEdge(0,i,v); 132 m+=v; 133 } 134 for(int i=k+1;i<=k+n;i++){ 135 scanf("%d",&p); 136 isap.AddEdge(i,k+n+1,1); 137 while(p--){ 138 scanf("%d",&v); 139 isap.AddEdge(v,i,1); 140 } 141 } 142 if(isap.Maxflow(0,k+n+1)<m){ 143 printf("No Solution! "); 144 }else{ 145 isap.Print(); 146 } 147 148 return 0; 149 }