您的位置:首页 > 理论基础 > 计算机网络

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++报错,求高人指点)

#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;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络 2010 sap ini c