zoukankan      html  css  js  c++  java
  • P3376 【模板】网络最大流

    题目描述:

    题目描述

    如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。

    输入格式

    第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

    接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)

    输出格式

    一行,包含一个正整数,即为该网络的最大流。

    输入输出样例

    输入 #1

    4 5 4 3
    4 2 30
    4 3 20
    2 3 20
    2 1 30
    1 3 40
    

    输出 #1

    50
    

    说明/提示

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=10,M<=25

    对于70%的数据:N<=200,M<=1000

    对于100%的数据:N<=10000,M<=100000

    样例说明:

    img

    题目中存在3条路径:

    4-->2-->3,该路线可通过20的流量

    4-->3,可通过20的流量

    4-->2-->1-->3,可通过10的流量(边4-->2之前已经耗费了20的流量)

    故流量总计20+20+10=50。输出50。

    思路:

    网络流模板题,再次试验了基于链式前向星的带有当前弧优化的Dinic算法

    注意cnt开始取1,有效从2开始,这是为了配合以后的e[i^1]运算找到相反边。

    比如:2(10)->3(11)

    如果是从1开始:1->0就不能找到相反边(WA了好多次QWQ)

    #include <iostream>
    #include <memory.h>
    #include <queue>
    #define INF 0x3f3f3f3f
    #define max_n 200005
    using namespace std;
    int n,m;
    int s,t;
    int flag;
    int max_flow = 0;
    int head[max_n];
    int cnt = 1;
    struct edge
    {
        int v;
        int nxt;
        int w;
    }e[max_n<<1];
    void add(int u,int v,int w)
    {
        ++cnt;
        e[cnt].v = v;
        e[cnt].w = w;
        e[cnt].nxt = head[u];
        head[u] = cnt;
    }
    
    int instack[max_n];
    int depth[max_n];
    int cur[max_n];
    int BFS()
    {
        //memset(depth,INF,sizeof(depth));
        //memset(instack,0,sizeof(instack));
        for(int i = 0;i<=n;i++)
        {
            cur[i] = head[i];depth[i] = INF;instack[i] = 0;
        }
        depth[s] = 0;
        queue<int> que;
        que.push(s);
        instack[s] = 1;
        while(!que.empty())
        {
            int u = que.front();
            instack[u] = 0;
            que.pop();
            for(int i = head[u];i;i=e[i].nxt)
            {
                int v = e[i].v;
                if(depth[v]>depth[u]+1&&e[i].w>0)
                {
                    depth[v] = depth[u]+1;
                    if(instack[v]==0)
                    {
                        que.push(v);
                        instack[v] = 1;
                    }
                }
            }
        }
        if(depth[t]!=INF) return 1;
        return 0;
    }
    int DFS(int u,int low)
    {
        int rlow = 0;
        if(u==t)
        {
            flag=1;
            max_flow += low;
            return low;
        }
        int used = 0;
        for(int i = cur[u];i;i=e[i].nxt)
        {
            cur[u] = i;
            int v = e[i].v;
            if(e[i].w>0&&depth[v]==depth[u]+1)
            {
                if(rlow=DFS(v,min(low-used,e[i].w)))
                {
                    used += rlow;
                    e[i].w -= rlow;
                    e[i^1].w += rlow;
                    if(used==low) break;
                }
            }
        }
        return used;
    }
    int Dinic()
    {
        while(BFS())
        {
            flag=1;
            while(flag==1)
            {
                flag = 0;
                DFS(s,INF);
            }
        }
        return max_flow;
    }
    int main()
    {
        cin >> n >> m >> s >> t;
        for(int i = 1;i<=m;i++)
        {
            int a,b,c;
            cin >> a >> b >> c;
            add(a,b,c);
            add(b,a,0);
        }
        cout << Dinic() << endl;
        return 0;
    }
    

    就是这样

  • 相关阅读:
    中国历史年代史的一些总结-缕清上下五千年
    struts2 自己定义表单
    &quot;What&#39;s New&quot; WebPart in SharePoint
    Tomcat+Servlet登录页面实例
    JAVA原始的导出excel文件,快捷通用 方便 还能够导出word文档哦
    Android开发 -- Bootloader
    NorFlash、NandFlash、eMMC比较区别【转】
    strspn() 和 strcspn() 函数【转】
    Device Tree(一):背景介绍【转】
    设备树使用手册【转】
  • 原文地址:https://www.cnblogs.com/zhanhonhao/p/11326626.html
Copyright © 2011-2022 走看看