POJ 1459 Power Network

84 篇文章 0 订阅
12 篇文章 0 订阅

这题是一个标准的最大流问题。

题目大意是:有n个点,其中nc个点是发电站,有np个点是用户,其他的是中转站,求最大流。

问题中存在着多源点和多汇点,我们可以把这些源点和汇点当作中转站,在虚拟一个超级源点和超级汇点,EK算法上模版,G++编译器1391MS。

下面是代码:

#include <iostream>
#include <string.h>
#include <queue>

using namespace std;
const int inf = 1<<30;
const int M =105;
int map1[M][M],pre[M],vis[M],n;
int EK()
{
    int i,ans=0,now,min1;
    queue <int> q;
    while(1)  //每循环一次找一次增广路
    {
        memset(pre,-1,sizeof(pre));
        memset(vis,0,sizeof(vis));
        while(!q.empty())
        {
            q.pop();
        }
        q.push(0);
        vis[0]=1;
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            if(now==n+1) //已经搜索到超级汇点  跳出循环
            {
                break;
            }
            for(i=0;i<=n+1;i++)
            {
                if(!vis[i]&&map1[now][i]>0)//如果节点i没被搜索过且节点now到节点i残余流量大于0
                {
                    pre[i]=now; //记录i的前驱节点是now
                    vis[i]=1;  //标记i点已经被访问过
                    q.push(i);  //把i点放入队列进行下一次BFS
                }
            }
        }
        if(!vis[n+1])
        {
            break;  //如果BFS完毕没有搜到到节点n+1的增广路,就已经找到最大流  跳出
        }
        min1=inf;
        for(i=n+1;i!=0;i=pre[i])
        {
            if(map1[pre[i]][i]<min1)  //寻找整个增广路上的残余流量的最小值,此为整个增广路的流量
            {
                min1=map1[pre[i]][i];
            }
        }
        ans+=min1;
        for(i=n+1;i!=0;i=pre[i])
        {
            map1[pre[i]][i]-=min1;//残余流量减少
            map1[i][pre[i]]+=min1;//已使用流量增加
        }
    }
    return ans;
}
int main()
{
    int np,nc,m,i;
    while(cin >> n >> np >> nc >> m)
    {
        char s;
        int u,v,w;
        memset(map1,0,sizeof(map1));
        for(i=0;i<m;i++)
        {
            cin >> s >> u >> s >> v >> s >> w;
            if(u!=v)
            {
                map1[u+1][v+1]=w;
            }
        }
        for(i=0;i<np;i++)
        {
            cin >> s >> v >> s >> w ;
            map1[0][v+1]=w;
        }
        for(i=0;i<nc;i++)
        {
            cin >> s >> u >> s>> w ;
            map1[u+1][n+1]=w;
        }
       cout << EK() << endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值