poj 1459Power Network_ http://poj.org/problem?id=1459

本文介绍了一个具体问题:如何求解最大电流量的问题,并将其转化为最大网络流问题。通过使用Edmonds-Karp算法,文章提供了一段完整的C++实现代码,详细展示了如何建立网络模型并求解最大流。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:有n个节点,np个发电站,nc个消耗站,其余的为中转站,有m条路径,求最大的电流量。

求解:增加一个源点和一个汇点,转化为最大网络流问题,使用Edmonds_Karp算法

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int n,np,nc,m;
#define maxn 105
#define INF 0xFFFFFFF
int cap[maxn][maxn],flow[maxn][maxn];
int pre[maxn],res[maxn];//res[i] 残量
int Edmonds_Karp(int start,int end)
{
    int maxflow=0;
    memset(flow,0,sizeof(flow));
    memset(pre,0,sizeof(pre));
    queue<int> q;
    while(true)
    {
        memset(res,0,sizeof(res));
        res[start]=INF;
        q.push(start);
        while(!q.empty()) //BFS寻找增广路
        {
            int u=q.front();
            q.pop();
            for(int v=1;v<=end;v++)
                if(!res[v]&&cap[u][v]>flow[u][v])
                {
                    res[v]=min(res[u],cap[u][v]-flow[u][v]);//start-v路径上的最小残量
                    //记录v的父亲,并加入队列中
                    pre[v]=u;
                    q.push(v);
                }
        }
        if(res[end]==0) return maxflow;//无法继续更新最大流量,则当前流已经是最大流
        for(int u=end;u!=start;u=pre[u])//从汇点往回走
        {
            flow[pre[u]][u]+=res[end];//更新正向流
            flow[u][pre[u]]-=res[end];//更新反向流
        }
        maxflow+=res[end]; //更新从s流出的总流量
    }
    return maxflow;
}
int main()
{
    char tmp;
    int a,b,c,d;
    while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
    {
        memset(cap,0,sizeof(cap));
        for(int i=1;i<=m;i++)
        {
            scanf("%c",&tmp);
            while(tmp!='(')
            {
                scanf("%c",&tmp);
            }
            scanf("%d",&a); a=a+2;
            scanf("%c",&tmp);
            scanf("%d",&b); b=b+2;
            scanf("%c",&tmp);
            scanf("%d",&d);
            cap[a][b]=d;
        }
        for(int i=1;i<=np;i++)
        {
            scanf("%c",&tmp);
            while(tmp!='(')
            {
                scanf("%c",&tmp);
            }
            scanf("%d",&a); a=a+2;
            scanf("%c",&tmp);
            scanf("%d",&d);
            cap[1][a]=d;
        }
        for(int i=1;i<=nc;i++)
        {
            scanf("%c",&tmp);
            while(tmp!='(')
            {
                scanf("%c",&tmp);
            }
            scanf("%d",&a);a=a+2;
            scanf("%c",&tmp);
            scanf("%d",&d);
            cap[a][n+2]=d;
        }
        n=n+2;
        int ans=Edmonds_Karp(1,n);
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值