2010成都赛区网络赛第五题---Food(hdu4292)
2012-09-22 00:17
405 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4292
题意:有F种食物和D种饮料和他们的具体数量。有N个人,每个人喜欢其中的某些食物或饮料,如何分配这些食物和饮料,能让更多的人,得到他们喜欢的一种食物和饮料。
思路:网络流。
建图思路:
(1)、取超级源点和超级汇点。
(2)、拆点,将一个人拆成i点和i'点,在i与i'之间建立一条容量为1的边。
(3)、在源点和食物之间建立一条边,容量为各自的数量。
(4)、在饮料和汇点之间建立一条边,容量为各自的数量。
(5)、在食物和i点之间建立一条边,容量为1。
(6)、在i'点和饮料之间建立一条边,容量为1。
代码:(该代码在hdu上用G++能过,用C++报错,求高人指点)
题意:有F种食物和D种饮料和他们的具体数量。有N个人,每个人喜欢其中的某些食物或饮料,如何分配这些食物和饮料,能让更多的人,得到他们喜欢的一种食物和饮料。
思路:网络流。
建图思路:
(1)、取超级源点和超级汇点。
(2)、拆点,将一个人拆成i点和i'点,在i与i'之间建立一条容量为1的边。
(3)、在源点和食物之间建立一条边,容量为各自的数量。
(4)、在饮料和汇点之间建立一条边,容量为各自的数量。
(5)、在食物和i点之间建立一条边,容量为1。
(6)、在i'点和饮料之间建立一条边,容量为1。
代码:(该代码在hdu上用G++能过,用C++报错,求高人指点)
#include <stdio.h> #include <string.h> #define MAXN 11000 #define INF 0x3f3f3f3f struct Edge{ int u; int v; int cap; int next; }edge[MAXN*40]; int cur[MAXN],head[MAXN],level[MAXN],gap[MAXN]; int stack[MAXN],que[MAXN]; int tot; void Ini() { tot = 0; memset(head,-1,sizeof(head)); } void addedge(int from,int to,int cap) { edge[tot].u = from; edge[tot].v = to; edge[tot].cap = cap; edge[tot].next = head[from]; head[from] = tot; tot++; edge[tot].u = to; edge[tot].v = from; edge[tot].cap = 0; edge[tot].next = head[to]; head[to] = tot; tot++; } void bfs(int src,int des) { int i; int front,rear; memset(gap,0,sizeof(gap)); memset(level,-1,sizeof(level)); front = rear = 0; level[des] = 0; gap[0] = 1; que[rear++] = des; while(front != rear) { int u = que[front++]; front = front%MAXN; for(i=head[u];i!=-1;i=edge[i].next) { int v = edge[i].v; if(edge[i].cap != 0 || level[v] != -1) continue; level[v] = level[u]+1; que[rear++]=v; rear = rear%MAXN; ++gap[level[v]]; } } } int sap(int src,int des) { bfs(src,des); int i; int res=0; memcpy(cur,head,sizeof(head)); int top=0; int u = src; while(level[src] < des+1) { if(u == des) { int temp = INF; int inser; for(i=0;i<top;i++) { if(temp > edge[stack[i]].cap) { temp = edge[stack[i]].cap; inser = i; } } for(i=0;i<top;i++) { edge[stack[i]].cap -= temp; edge[stack[i] ^ 1].cap += temp; } res += temp; top = inser; u = edge[stack[top]].u; } if(u != des && gap[level[u]-1] == 0) break; for(i=cur[u];i!=-1;i = edge[i].next) if( edge[i].cap != 0 && level[u] == level[edge[i].v]+1) break; if(i != -1) { cur[u] = i; stack[top++] = i; u = edge[i].v; } else { int min=des+1; for(i=head[u];i!=-1;i=edge[i].next) { if(edge[i].cap == 0) continue; if(min > level[edge[i].v]) { min = level[edge[i].v]; cur[u] = i; } } --gap[level[u]]; level[u] = min + 1; ++gap[level[u]]; if(u!=src) u = edge[stack[--top]].u; } } return res; } int main() { int i,j; int N,F,D; int food; int drink; char str[250]; while(scanf("%d%d%d",&N,&F,&D)!=EOF) { Ini(); int src= 0; int des = 2*N + F + D +1; for(i=1;i<=F;i++) { scanf("%d",&food); addedge(src,i,food); } for(i=F+2*N+1;i<=F+2*N+D;i++) { scanf("%d",&drink); addedge(i,des,drink); } for(i=F+1;i<=F+N;i++) addedge(i,i+N,1); for(i=1;i<=N;i++) { scanf("%s",str+1); for(j=1;j<=F;j++) { if(str[j] == 'Y') addedge(j,F+i,1); } } for(i=1;i<=N;i++) { scanf("%s",str+1); for(j=1;j<=D;j++) { if(str[j] == 'Y') addedge(F+N+i,F+2*N+j,1); } } printf("%d\n",sap(src,des)); } return 0; }
相关文章推荐
- HDU 4292 Food (成都赛区网络赛第五题,拆点网络流)
- Hdu 4292 Food (2012成都赛区网络赛第五题,拆点网络流)
- 成都赛区网络赛 hdu 4292 food
- hdu 4292 Food (成都赛区 网络赛 最大流 )
- hdu 4038 2011成都赛区网络赛H 贪心 ***
- 2013网络赛成都赛区1010
- 2013年ACM网络赛成都赛区
- 2012天津赛区网络赛第五题---A very hard mathematic problem(hdu4284)
- hdu 4296 (成都赛区2012网络赛)
- HDU/HDOJ 4038 2011成都赛区网络赛H题
- 2013网络赛成都赛区1003
- hdu 4731 2013成都赛区网络赛 找规律
- 2012 ACM/ICPC 成都赛区网络赛 HDU 4296
- hdu4737 A Bit Fun (2013 网络赛 成都赛区)
- 2010杭州赛区网络预赛 1006 Fate Stay Night (DP)
- HDU4292--Food拆点网络流
- Similarity (2010成都赛区,KM)
- HDU 4288 Coder 第37届ACM/ICPC 成都赛区网络赛1001题 (线段树)
- hdu 4703We Love MOE Girls (2013 网络赛 成都赛区)
- 2010杭州赛区网络预赛 1007 Tetris(DFS)