链接:https://www.oj.swust.edu.cn/oj/problem/show/1736
分析:模板题,增加源点和汇点s、t,从s向U中所有点连一条容量为1的边,从V中所有点向t中所有点连一条容量为1的边,然后求s-t最大流即为所求。最大流用的isap模板。
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 struct Edge{ 10 int from,to,cap,flow; 11 Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){} 12 }; 13 struct ISAP{ 14 int n,s,t; 15 vector<Edge> edges; 16 vector<int> G[maxn]; 17 bool vis[maxn]; 18 int d[maxn]; 19 int cur[maxn]; 20 int p[maxn]; 21 int num[maxn]; 22 23 void init(int n){ 24 this->n=n; 25 edges.clear(); 26 for(int i=0;i<n;i++)G[i].clear(); 27 } 28 29 void AddEdge(int from,int to,int cap){ 30 edges.push_back(Edge(from,to,cap,0)); 31 edges.push_back(Edge(to,from,0,0)); 32 G[from].push_back(edges.size()-2); 33 G[to].push_back(edges.size()-1); 34 } 35 36 void BFS(){ 37 memset(vis,0,sizeof(vis)); 38 queue<int> Q; 39 Q.push(t); 40 d[t]=0; 41 vis[t]=1; 42 while(!Q.empty()){ 43 int x=Q.front();Q.pop(); 44 for(int i=0;i<G[x].size();i++){ 45 Edge &e=edges[G[x][i]]; 46 if(!vis[e.to]){ 47 vis[e.to]=1; 48 d[e.to]=d[x]+1; 49 Q.push(e.to); 50 } 51 } 52 } 53 } 54 55 int Augment(){ 56 int x=t,a=INF; 57 while(x!=s){ 58 Edge &e=edges[p[x]]; 59 a=min(a,e.cap-e.flow); 60 x=edges[p[x]].from; 61 } 62 x=t; 63 while(x!=s){ 64 edges[p[x]].flow+=a; 65 edges[p[x]^1].flow-=a; 66 x=edges[p[x]].from; 67 } 68 return a; 69 } 70 71 int Maxflow(int s,int t){ 72 this->s=s;this->t=t; 73 int flow=0; 74 BFS(); 75 memset(num,0,sizeof(num)); 76 for(int i=0;i<n;i++)num[d[i]]++; 77 int x=s; 78 memset(cur,0,sizeof(cur)); 79 while(d[s]<n){ 80 if(x==t){ 81 flow+=Augment(); 82 x=s; 83 } 84 int ok=0; 85 for(int i=cur[x];i<G[x].size();i++){ 86 Edge &e=edges[G[x][i]]; 87 if(e.cap>e.flow&&d[x]==d[e.to]+1){ 88 ok=1; 89 p[e.to]=G[x][i]; 90 cur[x]=i; 91 x=e.to; 92 break; 93 } 94 } 95 if(!ok){ 96 int m=n-1; 97 for(int i=0;i<G[x].size();i++){ 98 Edge &e=edges[G[x][i]]; 99 if(e.cap>e.flow)m=min(m,d[e.to]); 100 } 101 if(--num[x]==0)break; 102 num[d[x]=m+1]++; 103 cur[x]=0; 104 if(x!=s)x=edges[p[x]].from; 105 } 106 } 107 return flow; 108 } 109 }isap; 110 111 int main(){ 112 // freopen("input.txt","r",stdin); 113 //freopen("output.txt","w",stdout); 114 int n,m,s,t; 115 scanf("%d%d",&m,&n); 116 isap.init(n+1); 117 for(int i=1;i<=m;i++)isap.AddEdge(0,i,1); 118 for(int i=m+1;i<=n;i++)isap.AddEdge(i,n+1,1); 119 while(1){ 120 scanf("%d%d",&s,&t); 121 if(s==-1&&t==-1)break; 122 isap.AddEdge(s,t,1); 123 } 124 int M=isap.Maxflow(0,n+1); 125 if(M==0){ 126 printf("No Solution! "); 127 }else{ 128 printf("%d ",M); 129 for(int i=0;i<isap.edges.size();i++){ 130 if(isap.edges[i].from!=0&&isap.edges[i].to!=n+1&&isap.edges[i].flow==1){ 131 printf("%d %d ",isap.edges[i].from,isap.edges[i].to); 132 } 133 } 134 } 135 return 0; 136 }