zoukankan      html  css  js  c++  java
  • 网络最大流dinic算法

    题目描述

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

    输入输出格式

    输入格式:

    第一行包含四个正整数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

    样例说明:

    题目中存在3条路径:

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

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

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

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

        先讲一下dinic的思路。

        与EK、FF相同,dinic也是通过找增广路来完成的。但与前两者不同的是,dinic是通过

    bfs把图分层,再找多条路径长度相同的增广路,再重复操作。

        另外,dinic找的增广路都是最短的,这样时间复杂度就会对?这可能比较玄学,具体的原理

    和证明我也不太清楚。

        下面是代码。

    #include<set>
    #include<map>
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define INF 2147483647
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    struct edge{
        int head,next,to,b;
    }f[400000];
    int tot,n,m,s,t;
    int mark[100000],dep[100000];
    long long ans;
    void add(int u,int v,int w){
        f[tot].next=f[u].head;f[u].head=tot;f[tot].to=v;f[tot].b=w;tot++;
    }
    bool bfs(){
        memset(mark,0,sizeof(mark));
        memset(dep,0,sizeof(dep));
        queue<int>Q; Q.push(s);
        dep[s]=1; mark[s]=1;
        while(!Q.empty()){
            int x=Q.front(); Q.pop();
            for(int i=f[x].head;i!=-1;i=f[i].next){
                int p=f[i].to;
                if(mark[p]||!f[i].b) continue;
                mark[p]=1;
                dep[p]=dep[x]+1;
                Q.push(p);
            }
            if(mark[t]) return 1;
        }
        return 0;
    }
    int dfs(int x,int a){
        if(x==t) return a;
        int flow=0;
        for(int i=f[x].head;i!=-1;i=f[i].next){
            int p=f[i].to;
            if(dep[p]!=dep[x]+1||!f[i].b) continue;
            int delta=dfs(p,min(a,f[i].b));
            flow+=delta;
            a-=delta;
            f[i].b-=delta;
            f[i^1].b+=delta;
            if(!a) break;
        }
        return flow;
    }
    void dinic(){
        while(bfs()) ans+=dfs(s,INF);
    }
    int main(){
        n=read();m=read();s=read();t=read();
        for(int i=1;i<=n;++i) f[i].head=-1;
        for(int i=1;i<=m;++i){
            int x,y,w;x=read();y=read();w=read();
            add(x,y,w);add(y,x,0);
        }
        dinic();
        printf("%lld",ans);
        return 0;
    }
    https://www.luogu.org/problem/show?pid=3376
  • 相关阅读:
    spring boot自动配置
    servlet类与Spring Controller类的关系
    Junit中的setup和teardown方法
    dependency的scope
    mapper的namespace
    mybatis缓存
    Ehcache(05)——缓存的查询
    Ehcache(04)——设置缓存的大小
    Ehcache(03)——Ehcache中储存缓存的方式
    Ehcache(02)——ehcache.xml简介
  • 原文地址:https://www.cnblogs.com/hanyu20021030/p/6602071.html
Copyright © 2011-2022 走看看