poj1459 多源多汇最大流

题目链接:http://poj.org/problem?id=1459

题目意思让我放弃了好几回,今天终于耐下心来读懂了

就不说题目意思了 看看输入输出:

Sample Input

2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20
7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7
         (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5
         (0)5 (1)2 (3)2 (4)1 (5)4

Sample Output

15
6

2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20 
2 1 1 2依次表示 共两个节点 生产能量的点1个 消费能量的点1个  传递能量的线2条
(0,1)20 (1,0)10 传递能量线   (起点,终点)最大传递的能量
(0)15 产生能量的点 (产生能量的点)产生的最大能量

(1)20 消费能量的点 (消费能量的点)消费的最大能量

最大流算法 构造两个虚拟点 一个代表源点 另一个代表汇点
源点连接产生能量的点 连线的权值为产生的能量
汇点连接消费能量的点 连线的权值为消费的能量

然后求源点到汇点的最大流

解法:EK

代码:

#include <stdio.h>
#include <stdlib.h>
int que[20000];
int map[150][150];
short flag[150],father[150];
int sta,end,sum;
short bfs(int n,int s,int h)
{
    int i,tem,f,min;
    f=0;
    min=10000;
    que[sta]=s;
    ++sta;
    for(i=0;i<=n+1;i++)
    {
        father[i]=-1;
        flag[i]=0;
    }
    while(sta!=end)
    {
        
        tem=que[end];
        ++end;
        if(map[tem][h]==0)
        {
            for(i=0;i<n;++i)
            {
                if(map[tem][i]!=0&&flag[i]==0)
                {                
                    que[sta]=i;
                    ++sta;
                    flag[i]=1;
                    father[i]=tem;
                }
            }
        }
        else
        {
            f=1;
            father[h]=tem;
            break;
        }
    }
    
    if(f==1)
    {
        for(i=h;father[i]!=-1;i=father[i])
        {

            if(min>map[father[i]][i])
            {
                min=map[father[i]][i];
            }
        }
         for(i=h;father[i]!=-1;i=father[i])
        {
               map[father[i]][i]-=min;
            
        }
        sum+=min;
        return 1;
    }
    else
    {
        return 0;
    }
}
int main(int argc, char** argv) {

    int n,np,nc,m,i,a,b,c,j;
    char str[50];
    while(scanf("%d %d %d %d",&n,&np,&nc,&m)!=EOF)
    {
         sum=0;
         sta=0;
         end=0;
         for(i=0;i<=n+1;i++)
         {
            for(j=0;j<=n+1;j++)
            {
                 map[i][j]=0;
            }
         }
        for(i=0;i<m;i++)
        {
            scanf("%s",str);
            sscanf(str,"(%d,%d)%d",&a,&b,&c);
            map[a][b]=c;
        }
        for(i=0;i<np;i++)
        {
            scanf("%s",str);
           sscanf(str," (%d)%d",&a,&b);          
           map[n][a]=b;
        }
         for(i=0;i<nc;i++)
        {
             scanf("%s",str);
            sscanf(str," (%d)%d",&a,&b);           
            map[a][n+1]=b;
        }
       while(bfs(n,n,n+1)==1)
        {
            sta=0;
            end=0;
           
        }
         
        printf("%d\n",sum);
    }
    return (EXIT_SUCCESS);
}
posted @ 2012-04-16 12:26  枫月寒  阅读(260)  评论(0编辑  收藏  举报