zoukankan      html  css  js  c++  java
  • POJPower Network (最大流)

    题目链接

    分析:

    这题描述的可不是一般的复杂.

    其时就是很多源点、很多汇点,使尽量多流量的到达汇点。

    因为有很多源点,就再设一个源点(0号),使得0号到其它源点的容量为其它源点的初始量,同样设一汇点(n+1),使得其它汇点到该汇点的容量为其它汇点的初始量,如此就把很多的源点和汇点看成普通的点,单源单汇最大流。

    最大流用的是白书上的增广路算法。

    AC代码如下:

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    
    using namespace std;
    
    const int maxn = 110;
    const int INF = (1<<30);
    
    int cap[maxn][maxn], flow[maxn][maxn];
    
    int EdmondsKarp(int s, int t, int n) {
        int p[maxn], a[maxn];
        queue<int> q;
    
        memset(flow, 0, sizeof(flow));
        int f = 0;
    
        while(true) {
            memset(a, 0, sizeof(a));
    
            a[s] = INF;
    
            q.push(s);
    
            while(!q.empty()) { //BFS 找增广路
                int u = q.front(); q.pop();
    
                for(int v=1; v<=n; v++) if(!a[v] && cap[u][v]>flow[u][v]){
                    //找到新节点v
                    p[v] = u; q.push(v);
                    a[v] = min(a[u], cap[u][v]-flow[u][v]);
                }
            }
    
            if(a[t] == 0) break;    //找不到,则当前流已经是最大流
    
            for(int u=t; u != s; u = p[u]) {    //从汇点往回走
                flow[p[u]][u] += a[t];  //更新正向流量
                flow[u][p[u]] -= a[t];  //更新反向流量
            }
    
            f += a[t];  //更新从 s 流出的流量
        }
    
        return f;
    }
    
    int main(){
        int n, np, nc, m;
        int u, v, c;
        char s[200];
    
        while(scanf("%d%d%d%d", &n, &np, &nc, &m) == 4) {
            memset(cap, 0, sizeof(cap));
    
            for(int i=0; i<m; i++) {
                scanf("%s", s);
                sscanf(s, "(%d,%d)%d", &u, &v, &c);
                u++; v++;
                cap[u][v] += c;
            }
    
            for(int i=0; i<np; i++) {                   //处理源点
                scanf("%s", s);
                sscanf(s, "(%d)%d", &v, &c);
                v++;
                cap[0][v] += c;
            }
    
            for(int i=0; i<nc; i++) {                   //处理汇点
                scanf("%s", s);
                sscanf(s, "(%d)%d", &u, &c);
                u++;
                cap[u][n+1] += c;
            }
    
            printf("%d
    ", EdmondsKarp(0, n+1, n+1));
        }
    
        return 0;
    }
  • 相关阅读:
    精讲响应式WebClient第6篇-请求失败自动重试机制,强烈建议你看一看
    dubbo实战之三:使用Zookeeper注册中心
    dubbo实战之二:与SpringBoot集成
    dubbo实战之一:准备和初体验
    树莓派4B安装官方Ubuntu20 Server版(64位)
    JUnit5学习之八:综合进阶(终篇)
    纯函数
    函数式编程基本概念
    vscod使用指南
    实际使用Elasticdump工具对Elasticsearch集群进行数据备份和数据还原
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3255316.html
Copyright © 2011-2022 走看看