Edmonds-Karp算法,最大流POJ(1459)

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

解题报告:

电力调度站不涉及流的产生和消耗,不用考虑,Edmonds-Karp算法,就是利用剩余网络和增广路来解决,网络中的最大流。

原理:剩余网络,就是一种回退,构造完在剩余网络后,在剩余网络中找一条增广路,其中的最小流量,每个边加上这个最小流量或者减去这个最小流量,那么流就变成最大的了。

在加上或者减去这个最小流量时,初始化flow[][]这个剩余网络为0,最小流量node[v]=min(node[u],cap[u][v]-flow[u][v]),重新更新flow[][]+=node[t]后,就是真正的剩余网络了,cap[u][v]-flow[u][v]就表示的是这条边最大的流量了,这里也可以看出初始化flow[][]为0的目的了。

然后是,增广路的搜索,BFS广度优先搜索出每一条增广路,没找到一条增广路,就更新flow剩余网络,直到不存在增广路,就是说,直到原网络没有了任何的可以加上的流了。

这个题目,不能直接用传统意义上的最大流,因为这么没有一个绝对的源点和汇点,所以要建一个超级源点s,和超级汇点,n,n+1;

#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#define MAX 120

using namespace std;

int n;                          ///节点数
int np;                         ///发电站数
int nc;                         ///消费者数
int m;                          ///传输线数
int cap[MAX][MAX];              ///网络的邻接矩阵

int from,to,value;

///形参s是超级源点,形参t是超级汇点
int EKarp(int s,int t) {
    queue<int> Q;               ///用于BFS的搜索队列
    int flow[MAX][MAX];         ///剩余网络的邻接矩阵
    int pre[MAX];               ///增广路径
    int node[MAX];              ///增广路径上的最小流
    int u,v;
    int maxflow=0;              ///网络的最大流
    ///剩余网络的初始化
    memset(flow,0,sizeof(flow));

    ///不断寻找增广路径
    while(true) {
        Q.push(s);
        memset(node,0,sizeof(node));
        node[s]=100000;         ///最小流量初值,无穷大

        ///BFS算法,搜索增广路径
        while(!Q.empty()) {
            u=Q.front();
            Q.pop();

            for(v=0; v<=t; v++) {
                if(!node[v]&&cap[u][v]>flow[u][v]) {
                    Q.push(v);
                    node[v]=min(node[u],cap[u][v]-flow[u][v]);
                    pre[v]=u;
                }
            }
        }

        ///当瓶颈容量为0时,说明不存在增广路径,搜索结束
        if(node[t]==0) break;
        ///根据增广路径和瓶颈容量,更新剩余网络
        for(u=t; u!=s; u=pre[u]) {
            flow[pre[u]][u]+=node[t];
            flow[u][pre[u]]-=node[t];
        }

        maxflow+=node[t];
    }
    return maxflow;     ///总流量累加
}

int main() {
    while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) {
        memset(cap,0,sizeof(cap));

        ///读取输电线的数据
        while(m--) {
            scanf(" (%d,%d)%d",&from,&to,&value);
            cap[from][to]=value;
        }

        ///读取发电站数据,构造超级源点
        while(np--) {
            scanf(" (%d)%d",&from,&value);
            cap[n][from]=value;
        }

        ///读取消费者数据,构造超级汇点
        while(nc--) {
            scanf(" (%d)%d",&from,&value);
            cap[from][n+1]=value;
        }

        printf("%d\n",EKarp(n,n+1));
    }
    return 0;
}

时间: 2024-10-25 21:19:37

Edmonds-Karp算法,最大流POJ(1459)的相关文章

POJ 1459 Power Network 经典网络流构图问题 最大流,EK算法

题目链接:POJ 1459 Power Network Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 23347   Accepted: 12231 Description A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport line

POJ 1459 &amp; ZOJ 1734 Power Network (网络最大流)

http://poj.org/problem?id=1459 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1734 Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 22674   Accepted: 11880 Description A power network consists of nodes (power s

POJ 1459 Power Network(网络流 最大流 多起点,多汇点)

Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 22987   Accepted: 12039 Description A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be supplied

poj 1459 Power Network, 最大流,多源多汇

点击打开链接 多源多汇最大流,虚拟一个源点s'和一个汇点t',原来的源点.汇点向它们连边. #include<cstdiO> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; const int maxn = 500 + 5; const int INF = 100

POJ 1459 Power Network(ISAP 裸最大流)

题目链接:http://poj.org/problem?id=1459 注意输入格式就行,还是ISAP #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> const int N = 210; const int maxn = 300; const int ma

poj 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 7个点包括电站和用户,2个电站,3个用户,13条边,输入13条边,输入2个电站,输入3个用户 Sample Output 15 6 增加一个源点一个汇点

POJ 1459 Power Network 最大流

建模不难,就读入有点麻烦,无脑拍完dinic 1A happy- #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #i

初涉网络流 POJ 1459 Power Network

怒搞一下午网络流,又去我一块心病. 从2F到SAP再到Dinic终于过掉了.可是书上说Dinic的时间复杂度为v*v*e.感觉也应该超时的啊,可是过掉了,好诡异. 后两种算法都是在第一种的基础上进行优化.第一种方法就是不停的寻找增广路,后两种引进了层次网络的概念,第三种又改善了寻找增广路的方法. 现在只能理解到这里了... #include <algorithm> #include <iostream> #include <cstring> #include <c

Edmonds 开花算法

Edmonds 开花算法 input: 图G,匹配M,未饱和点u idea:  查找从 u 开始的 M-交错路径,对每个顶点记录父亲节点.发现花朵,则收缩. 维护 S 和 T,S 表示沿着已经饱和的边抵达的顶点构成的集合,收缩过程中的新顶点也属于 S, T表示当前图中沿着未饱和的边抵达的顶点构成的集合 ,一旦遇到另一个未饱和的顶点,则得到增广路. init: S = { u }, T = ? iterate: 若 S 中无未饱和的点,则不存在从 u 开始的增广路,算法停止. 否则,取出一个未饱和