• HDU-3549-Flow Problem


    链接:https://vjudge.net/problem/HDU-3549

    题意:

    给定多张图,求从1到n的最大流

    思路:

    网络流最大流

    增广路算法,具体看注释。

    代码:

    #include <iostream>
    #include <memory.h>
    #include <vector>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <math.h>
    #include <queue>
    #include <string>
    
    using namespace std;
    
    typedef long long LL;
    
    const int MAXM = 1000 + 10;
    const int MAXN = 20;
    const int INF = 1e9 + 10;
    
    int n, m;
    
    struct Edge
    {
        int _from, _to, _cap, _flow;
        Edge(int from, int to, int cap, int flow):_from(from), _to(to), _cap(cap), _flow(flow){};
    };
    
    vector<Edge> edges;//记录每条边
    vector<int> G[MAXN];//记录图,每个节点的边
    int a[MAXN], p[MAXN];
    //a数组记录每次找增广路时候每个节点对应能加的流
    //p数组记录流经的点对应的线路的编号
    void Init()
    {
        edges.clear();
        for (int i = 0;i < n;i++)
            G[i].clear();
    }
    
    int Solve()
    {
        int flow = 0;//总流量
        while (1)
        {
            memset(a, 0, sizeof(a));//每次找增广路初始化
            queue<int> que;//每次bfs的队列
            que.push(1);
            a[1] = INF;
            while (!que.empty())
            {
                int x = que.front();
                que.pop();
                for (int i = 0;i < G[x].size();i++)
                {
                    Edge & e = edges[G[x][i]];
                    if (!a[e._to] && e._cap > e._flow)
                    {
                        //a为0表示没有流过这个点同时流量小于容量
                        p[e._to] = G[x][i];
                        a[e._to] = min(a[x], e._cap - e._flow);
                        //能流的流量是线路最大流量和上一个节点的值中的较小值
                        que.push(e._to);//新节点进队
                    }
                }
                if (a[n] > 0)//如果流到了终点,break
                    break;
            }
            if (a[n] == 0)//如果终点流不到,表示增广路找不到,
                break;
            for (int u = n;u != 1;u = edges[p[u]]._from)
            {
                edges[p[u]]._flow += a[n];
                edges[p[u] ^ 1]._flow -= a[n];//表示与正向对应的反向的边
            }
            flow += a[n];
        }
        return flow;
    }
    
    int main()
    {
        int t;
        int l, r, c, cnt = 0;
        scanf("%d", &t);
        while (t--)
        {
    
            scanf("%d%d", &n, &m);
            Init();
            for (int i = 1;i <= m;i++)
            {
                scanf("%d%d%d", &l, &r, &c);
                edges.push_back(Edge(l, r, c, 0));
                edges.push_back(Edge(r, l, 0, 0));//增加反向边 保证能找到最大流
                G[l].push_back(edges.size() - 2);
                G[r].push_back(edges.size() - 1);
            }
            cout << "Case " << ++cnt << ": ";
            cout << Solve() << endl;
        }
    
        return 0;
    }
    

      

     
  • 相关阅读:
    面向对象第三单元博客作业
    面向对象编程第2次总结(电梯作业)
    面向对象编程第1次总结
    OOP 第四章博客总结
    OO 第三章总结
    OOP 第二章作业总结
    Java 设计模式 -- 代理模式
    ASID 与 MIPS 中 TLB 相关
    Java 锁机制总结
    OOP 第一章作业总结
  • 原文地址:https://www.cnblogs.com/YDDDD/p/10544494.html
Copyright © 2020-2023  润新知