• 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
    ",EKarp(n,n+1));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    MVC中权限管理
    ElasticSearch作为Windows服务启动
    linux下mysql常用的一些命令
    用Markdown写博客
    JAVA设计模式——简单工厂
    JAVA设计模式——单例模式
    JAVA设计模式——开篇
    Centos7.3安装和配置Mysql5.7
    java开发环境配置——IDEA SVN的使用
    java开发环境配置——IntelliJ IDEA
  • 原文地址:https://www.cnblogs.com/TreeDream/p/5506511.html
Copyright © 2020-2023  润新知