洛谷P1231 教辅的组成 网络流

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=50004;
const int INF=10000000;
# define  pb push_back
int s,t;
struct Edge{
  int from,to,cap;
  Edge(int u,int v,int c):from(u),to(v),cap(c) {}
};
struct Dicnic{
   vector<Edge>edges;
   vector<int>G[maxn];
   int d[maxn],vis[maxn],cur[maxn];
   queue<int>Q;
   void addedge(int u,int v,int c){
    edges.pb(Edge(u,v,c));               
    edges.pb(Edge(v,u,0));               
    int m=edges.size();
    G[u].pb(m-2);
    G[v].pb(m-1);
   }
   int BFS()
   {
    memset(vis,0,sizeof(vis));
    d[s]=0,vis[s]=1;Q.push(s);
    while(!Q.empty()){
      int u=Q.front();Q.pop();
      int sz=G[u].size();
      for(int i=0;i<sz;++i){
        Edge e=edges[G[u][i]];
        if(!vis[e.to]&&e.cap>0){
          d[e.to]=d[u]+1,vis[e.to]=1;
          Q.push(e.to);
        }
      }
    }
    return vis[t];
   }
   int dfs(int x,int a){
       if(x==t)return a;
       int sz=G[x].size();
       int f,flow=0;
       for(int i=cur[x];i<sz;++i){
        Edge e=edges[G[x][i]];
        cur[x]=i;  
        if(d[e.to]==d[x]+1&&e.cap>0){
          f=dfs(e.to,min(a,e.cap));
          if(f)
          {
                int u=G[x][i];
                a-=f;
                edges[u].cap-=f;
                edges[u^1].cap+=f;
                flow+=f;
                if(a==0)break;
          }
        }
       }
       return flow;
   }
   int maxflow(){
    int ans=0;
    while(BFS()){
      memset(cur,0,sizeof(cur));
      ans+=dfs(s,INF);
    }
    return ans;
   }
}op;
int main()
{
	int n1,n2,n3,m;
	scanf("%d%d%d",&n1,&n2,&n3);
	scanf("%d",&m);
	s=0,t=n2+n1*2+n3+3;
	while(m--){
		int a,b;scanf("%d%d",&a,&b);
          op.addedge(b,n2+a,1);
	}                                              //练习册和书
	for(int i=1;i<=n2;++i)op.addedge(s,i,1);              //源点到练习册
	for(int i=n2+1;i<=n2+n1;++i)op.addedge(i,i+n1,1);      //书的容量限制
	scanf("%d",&m);   
     while(m--){
     	     int a,b;
     	     scanf("%d%d",&a,&b);
     	     op.addedge(n2+a+n1,n2+n1+n1+b,1);           //书到答案
     }
     for(int i=n2+2*n1+1;i<=n2+2*n1+n3;++i)
     	     op.addedge(i,t,1);                           //答案到汇点
     	int ans=op.maxflow();
     	printf("%d",ans);
     	return 0;
}

  

原文地址:https://www.cnblogs.com/guangheli/p/10365858.html