P3376 网络最大流

来源:互联网 发布:旺旺名是淘宝名吗 编辑:程序博客网 时间:2024/06/03 22:49

题目描述

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

输入输出格式

输入格式:
第一行包含四个正整数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 算法

#include<iostream>#include<cstdio>#include<queue>#include<vector>#include<cstring>using namespace std;#define INF 0x7fffffff#define maxn 10001#define min(x,y) (x<y?x:y)inline void read(int& a){    char c=getchar();    for(;(c<'0'||c>'9')&&c!='-';c=getchar());    bool f=0;if(c=='-') {f=1;c=getchar();};    for(a=0;c>='0'&&c<='9';c=getchar()) a=a*10+c-'0';    if(f) a=-a;}struct Edge{    int from,to,cap,flow;};struct Dinic{    int s,t,d[maxn],cur[maxn];    bool vis[maxn];    vector<Edge> edges;    vector<int> G[maxn];    void init(int s,int t,int n){        this->s=s;this->t=t;        for(int i=0;i<=n;i++) G[i].clear();        edges.clear();    }    void AddEdge(int from,int to,int cap){        edges.push_back((Edge){from,to,cap,0});        edges.push_back((Edge){to,from,0,0});        int m=edges.size();        G[from].push_back(m-2);        G[to].push_back(m-1);    }    bool BFS(){        queue<int> Q;Q.push(s);        memset(vis,0,sizeof(vis));        vis[s]=1;d[s]=0;        while(!Q.empty()){            int x=Q.front();Q.pop();            for(int i=0;i<G[x].size();i++){                Edge& e=edges[G[x][i]];                if(!vis[e.to]&&e.cap>e.flow){                    vis[e.to]=1;d[e.to]=d[x]+1;                    Q.push(e.to);                }            }        }        return vis[t];    }    int DFS(int x,int a){        if(x==t||a==0) return a;        int flow=0,f;        for(int& i=cur[x];i<G[x].size();i++){            Edge& e=edges[G[x][i]];            if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){                e.flow+=f;edges[G[x][i]^1].flow-=f;                flow+=f;a-=f;                if(a==0) break;            }        }        return flow;    }    int MaxFlow(){        int flow=0;        while(BFS()){            memset(cur,0,sizeof(cur));            flow+=DFS(s,INF);        }        return flow;    }};int n,m,t,s,u,v,w,tmp;Dinic din;int main(){    freopen("1.in","r",stdin);    read(n);read(m);read(s);read(t);    din.init(s,t,n);    for(int i=1;i<=m;i++){        read(u);read(v);read(w);        din.AddEdge(u,v,w);    }    printf("%d\n",din.MaxFlow());}
0 0