hdu 4292 Food 最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4292
You, a part-time dining service worker in your college’s dining hall, are now confused with a new problem: serve as many people as possible.
The issue
comes up as people in your college are more and more difficult to serve with
meal: They eat only some certain kinds of food and drink, and with requirement
unsatisfied, go away directly.
You have prepared F (1 <= F <= 200)
kinds of food and D (1 <= D <= 200) kinds of drink. Each kind of food or
drink has certain amount, that is, how many people could this food or drink
serve. Besides, You know there’re N (1 <= N <= 200) people and you too can
tell people’s personal preference for food and drink.
Back to your goal: to
serve as many people as possible. So you must decide a plan where some people
are served while requirements of the rest of them are unmet. You should notice
that, when one’s requirement is unmet, he/she would just go away, refusing any
service.
题意描述:你准备了F种食物(F<=200)和D种饮料(D<=200),每种食物和饮料都有一定的数量。有n个人(n<=200),每个人都有喜欢的食物和饮料并且只能吃自己喜欢的食物、喝喜欢的饮料,求出能够吃到喜欢的食物并喝到喜欢的饮料的最大人数。
算法分析:运用网络最大流求解即可。新增源点from和汇点to,from->食物(w为食物数量),饮料->to(w为饮料数量),对每个人 i 拆边 i 和 i+n ,喜欢的食物->i(w为1),i -> i+n(w为1),i+n->喜欢的饮料(w为1)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 0x7fffffff 10 using namespace std; 11 const int maxn=200+10; 12 const int M = 999999; 13 14 int n,F,D; 15 int from,to,d[maxn*10]; 16 struct node 17 { 18 int v,flow; 19 int next; 20 }edge[M*2]; 21 int head[maxn*10],edgenum; 22 23 void add(int u,int v,int flow) 24 { 25 edge[edgenum].v=v ;edge[edgenum].flow=flow; 26 edge[edgenum].next=head[u]; 27 head[u]=edgenum++; 28 29 edge[edgenum].v=u ;edge[edgenum].flow=0; 30 edge[edgenum].next=head[v]; 31 head[v]=edgenum++; 32 } 33 34 int bfs() 35 { 36 memset(d,0,sizeof(d)); 37 d[from]=1; 38 queue<int> Q; 39 Q.push(from); 40 while (!Q.empty()) 41 { 42 int u=Q.front() ;Q.pop() ; 43 for (int i=head[u] ;i!=-1 ;i=edge[i].next) 44 { 45 int v=edge[i].v; 46 if (!d[v] && edge[i].flow>0) 47 { 48 d[v]=d[u]+1; 49 Q.push(v); 50 if (v==to) return 1; 51 } 52 } 53 } 54 return 0; 55 } 56 57 int dfs(int u,int flow) 58 { 59 if (u==to || flow==0) return flow; 60 int cap=flow; 61 for (int i=head[u] ;i!=-1 ;i=edge[i].next) 62 { 63 int v=edge[i].v; 64 if (d[v]==d[u]+1 && edge[i].flow>0) 65 { 66 int x=dfs(v,min(cap,edge[i].flow)); 67 cap -= x; 68 edge[i].flow -= x; 69 edge[i^1].flow += x; 70 if (cap==0) return flow; 71 } 72 } 73 return flow-cap; 74 } 75 76 int dinic() 77 { 78 int sum=0; 79 while (bfs()) sum += dfs(from,inf); 80 return sum; 81 } 82 83 int main() 84 { 85 while (scanf("%d%d%d",&n,&F,&D)!=EOF) 86 { 87 memset(head,-1,sizeof(head)); 88 edgenum=0; 89 from=F+2*n+D+1; 90 to=from+1; 91 int a; 92 for (int i=1 ;i<=F ;i++) 93 { 94 scanf("%d",&a); 95 add(from,i,a); 96 } 97 for (int i=1 ;i<=D ;i++) 98 { 99 scanf("%d",&a); 100 add(F+2*n+i,to,a); 101 } 102 char str[maxn]; 103 memset(str,0,sizeof(str)); 104 for (int i=1 ;i<=n ;i++) 105 { 106 scanf("%s",str+1); 107 for (int j=1 ;j<=F ;j++) 108 { 109 if (str[j]=='Y') 110 add(j,F+i,1); 111 } 112 } 113 for (int i=1 ;i<=n ;i++) 114 { 115 scanf("%s",str+1); 116 for (int j=1 ;j<=D ;j++) 117 { 118 if (str[j]=='Y') 119 add(F+n+i,F+2*n+j,1); 120 } 121 } 122 for (int i=1 ;i<=n ;i++) 123 add(F+i,F+n+i,1); 124 printf("%d\n",dinic()); 125 } 126 return 0; 127 }