网络流(dinic算法)

北城余情 提交于 2020-02-06 20:08:56

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

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

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=2e5+10;
//int read(){
//    int x=0;
//    int zf=1;
//    char ch=' ';
//    while(ch != '-'&&(ch<'0'||ch>'9')) ch=getchar();
//    if(ch=='-') zf=-1,ch=getchar();
//    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
//    return x*ch;
//}
struct node{
    int to,w,nxt;
}e[maxn];
int n,m,s,t;
int head[maxn],cnt;
int dep[maxn];
void addedge(int u,int v,int w){
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].nxt=head[u];
    head[u]=cnt++;
}
int bfs(int node)
{
    memset(dep,0,sizeof(dep));
    dep[node]=1;
    queue<int>Q;
    Q.push(node);
    while(!Q.empty())
    {
        int x=Q.front();Q.pop();
        for(int i=head[x];i!=-1;i=e[i].nxt)
        {
            int y=e[i].to;
            int w=e[i].w;
            if(!dep[y]&&w)
            {
                dep[y]=dep[x]+1;
                Q.push(y);
            }
        }
    }
    return dep[t];
}
int dfs(int u,int flow)
{
    if(u==t) return flow;
    int ans=0;
    for(int i=head[u];i!=-1;i=e[i].nxt)
    {
        int y=e[i].to,w=e[i].w;
        if(w&&dep[y]==dep[u]+1)
        {
            int t=dfs(y,min(flow,w));
            e[i].w-=t;
            e[i^1].w+=t;
            ans+=t;
            flow-=t;
        }
    }
    if(ans==0)
    {
        dep[u]=0;
    }
    return ans;
}
int main()
{
    memset(head,-1,sizeof(head));
    cin>>n>>m>>s>>t;
    for(int i=0;i<m;i++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        addedge(u,v,w);
        addedge(v,u,0);
    }
    int ans=0;
    while(bfs(s))
    {
        ans+=dfs(s,0x3f3f3f3f);
    }
    cout<<ans<<endl;
    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!