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

    题目描述

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

    输入输出格式

    输入格式:

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

        EK和FF的区别在于EK求任意路径是用的是BFS,而FF是DFS,所以不得不说EK比FF快太多了。

        (Dinic和ISAP:两个骑三轮的有什么好比的)

        但EK的思路还是一样的,这里不再细讲。

    #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 next,to,head,b;
    }f[440000];
    int n,m,s,t,tot;
    int a[20000],pre[440000],path[440000];
    long long ans;
    void add(int u,int v,int w){
        f[tot].next=f[u].head;f[u].head=tot;f[tot].b=w;f[tot].to=v;tot++;
    }
    void EK(){
        ans=0;
        for(;;){
            memset(a,0,sizeof(a));
            memset(pre,0,sizeof(pre));
            memset(path,0,sizeof(path));
            queue<int> Q; Q.push(s);
            a[s]=INF;
            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(a[p]!=0||!f[i].b) continue;
                    a[p]=min(a[x],f[i].b);
                    pre[p]=x; path[p]=i;
                    Q.push(p);
                }
                if(a[t]) break;
            }
            if(!a[t]) return;
            ans+=a[t];
            for(int i=t;i!=s;i=pre[i]){
                int x=path[i];
                f[x].b-=a[t];
                f[x^1].b+=a[t];
            }
        }
    }
    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);
        }
        EK();
        printf("%lld",ans);
        return 0;
    }
    
    //https://www.luogu.org/problem/show?pid=3376#sub
  • 相关阅读:
    Log4j2_java日志使用
    Log4j_java日志使用
    DB_常用知识
    Oracle_内置信息
    Loadrunner使用时IE浏览器打不开怎么办
    性能测试
    python条件语句及循环语句
    计算机网络
    单元测试
    边界条件测试
  • 原文地址:https://www.cnblogs.com/hanyu20021030/p/6567982.html
Copyright © 2011-2022 走看看