• 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;
    }
    

      

     
  • 相关阅读:
    自学Linux Shell5.2-shell内建命令history alias
    自学Linux Shell5.1-shell父子关系
    vue2.0 实现导航守卫(路由守卫)
    vue2.0 关于Vue实例的生命周期
    vue2.0 正确理解Vue.nextTick()的用途
    vue2.0 项目build后资源文件报错404的解决方案
    vue2.0 vetur插件提示 'v-for' directives require 'v-bind:key' directives 的解决办法
    vue2.0 微信oauth认证的正确调用位置
    vue2.0 样式表引入的方法 css sass less
    vue2.0 配置sass
  • 原文地址:https://www.cnblogs.com/YDDDD/p/10544494.html
Copyright © 2020-2023  润新知