POJ 3281 Dining(最大流)

http://poj.org/problem?id=3281

题意:

有n头牛,F种食物和D种饮料,每头牛都有自己喜欢的食物和饮料,每种食物和饮料只能给一头牛,每头牛需要1食物和1饮料。问最多能满足几头牛的需求。

思路:

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 #include<set>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef long long ull;
 15 typedef pair<int,int> pll;
 16 const int INF = 0x3f3f3f3f;
 17 const int maxn = 1000 + 5;
 18 
 19 struct Edge
 20 {
 21     int from,to,cap,flow;
 22     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
 23 };
 24 
 25 struct Dinic
 26 {
 27     int n,m,s,t;
 28     vector<Edge> edges;
 29     vector<int> G[maxn];
 30     bool vis[maxn];
 31     int cur[maxn];
 32     int d[maxn];
 33 
 34     void init(int n)
 35     {
 36         this->n=n;
 37         for(int i=0;i<n;++i) G[i].clear();
 38         edges.clear();
 39     }
 40 
 41     void AddEdge(int from,int to,int cap)
 42     {
 43         edges.push_back( Edge(from,to,cap,0) );
 44         edges.push_back( Edge(to,from,0,0) );
 45         m=edges.size();
 46         G[from].push_back(m-2);
 47         G[to].push_back(m-1);
 48     }
 49 
 50     bool BFS()
 51     {
 52         queue<int> Q;
 53         memset(vis,0,sizeof(vis));
 54         vis[s]=true;
 55         d[s]=0;
 56         Q.push(s);
 57         while(!Q.empty())
 58         {
 59             int x=Q.front(); Q.pop();
 60             for(int i=0;i<G[x].size();++i)
 61             {
 62                 Edge& e=edges[G[x][i]];
 63                 if(!vis[e.to] && e.cap>e.flow)
 64                 {
 65                     vis[e.to]=true;
 66                     d[e.to]=d[x]+1;
 67                     Q.push(e.to);
 68                 }
 69             }
 70         }
 71         return vis[t];
 72     }
 73 
 74     int DFS(int x,int a)
 75     {
 76         if(x==t || a==0) return a;
 77         int flow=0, f;
 78         for(int &i=cur[x];i<G[x].size();++i)
 79         {
 80             Edge &e=edges[G[x][i]];
 81             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
 82             {
 83                 e.flow +=f;
 84                 edges[G[x][i]^1].flow -=f;
 85                 flow +=f;
 86                 a -=f;
 87                 if(a==0) break;
 88             }
 89         }
 90         return flow;
 91     }
 92 
 93     int Maxflow(int s,int t)
 94     {
 95         this->s=s; this->t=t;
 96         int flow=0;
 97         while(BFS())
 98         {
 99             memset(cur,0,sizeof(cur));
100             flow +=DFS(s,INF);
101         }
102         return flow;
103     }
104 }DC;
105 
106 int n,F,D;
107 
108 int main()
109 {
110     //freopen("in.txt","r",stdin);
111     while(~scanf("%d%d%d",&n,&F,&D))
112     {
113         int src=0, dst=F+D+2*n+1;
114         DC.init(dst+1);
115 
116         for(int i=1;i<=F;i++)  DC.AddEdge(src,i,1);
117         for(int i=1;i<=D;i++)  DC.AddEdge(F+i,dst,1);
118 
119         for(int i=1;i<=n;i++)
120         {
121             DC.AddEdge(F+D+i,F+D+n+i,1);
122             int num1,num2;
123 
124             scanf("%d%d",&num1,&num2);
125             while(num1--)
126             {
127                 int x;
128                 scanf("%d",&x);
129                 DC.AddEdge(x,F+D+i,1);
130             }
131             while(num2--)
132             {
133                 int x;
134                 scanf("%d",&x);
135                 DC.AddEdge(F+D+n+i,F+x,1);
136             }
137         }
138         printf("%d
",DC.Maxflow(src,dst));
139     }
140     return 0;
141 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7212113.html