网络流最大流代码

最近学习了网络流最大流的三种做法,有Ford-Fulkerson,还有EdmondsKarp,Dinic

贴代码,这个是Ford-Fulkerson

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
typedef long long LL;
const int oo=2147483647;
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int maxn=100010;
queue <int> Q;
int first[maxn],next[maxn],u[maxn],v[maxn],w[maxn],rev[maxn],n,m,vis[maxn],a,b,c;
void addEdge(int i,int a,int b,int c,int d)
{
    u[i]=a;v[i]=b;w[i]=c;rev[i]=d;
    next[i]=first[a];first[a]=i;
}
int dfs(int x,int t,int a)
{
    if(x==t)return a;
    vis[x]=1;
    for(int i=first[x];i!=-1;i=next[i])
        if(!vis[v[i]] && w[i]>0)
        {
            int d=dfs(v[i],t,min(a,w[i]));
            if(d>0)
            {
                w[i]-=d;w[rev[i]]+=d;
                return d;
            }
        }
    return 0;
}
int FF(int s,int t)
{
    int flow=0;
    while(1)
    {
        memset(vis,0,sizeof(vis));
        int f=dfs(s,t,oo);
        if(!f)return flow;
        flow+=f;
    }
}
int main()
{
    memset(first,-1,sizeof(first));
    n=read();m=read();
    for(int i=0;i<m;i++)
    {
        a=read();b=read();c=read();
        addEdge(2*i,a,b,c,2*i+1);
        addEdge(2*i+1,b,a,0,2*i);
    }    
    printf("%d",FF(1,n));
}

还有EdmondsKarp

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
typedef long long LL;
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
queue <int> Q;
const int maxn=100010;
int first[maxn],next[maxn],u[maxn],v[maxn],w[maxn],rev[maxn],n,m,a,b,c,pre[maxn];
bool vis[maxn];
void addEdge(int i,int a,int b,int c,int d)
{
    u[i]=a;v[i]=b;w[i]=c;rev[i]=d;
    next[i]=first[a];first[a]=i;
}
bool BFS(int s,int t)
{
    memset(pre,-1,sizeof(pre));
    memset(vis,0,sizeof(vis));
    while(Q.size())Q.pop();
    vis[s]=true;Q.push(s);
    while(Q.size())
    {
        int p=Q.front();Q.pop();
        for(int i=first[p];i!=-1;i=next[i])
            if(!vis[v[i]] && w[i]>0)
            {
                pre[v[i]]=i;
                vis[v[i]]=1;
                if(v[i]==t)return 1;
                Q.push(v[i]);
            }
    }
    return 0;
}
int EK(int s,int t)
{
    int maxflow=0,d;
    while(BFS(s,t))
    {
        d=w[pre[t]];
        for(int i=pre[t];i!=-1;i=pre[u[i]])d=min(d,w[i]);
        for(int i=pre[t];i!=-1;i=pre[u[i]])w[i]-=d,w[rev[i]]+=d;
        maxflow+=d;
    }
    return maxflow;
}
int main()
{
    memset(first,-1,sizeof(first));
    n=read();m=read();
    for(int i=0;i<m;i++)
    {
        a=read();b=read();c=read();
        addEdge(2*i,a,b,c,2*i+1);
        addEdge(2*i+1,b,a,0,2*i);
    }
    printf("%d\n",EK(1,n));
    return 0;
}


还有Dinic

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
typedef long long LL;
const int oo=2147483647;
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int maxn=100010;
queue <int> Q;
int first[maxn],next[maxn],u[maxn],v[maxn],w[maxn],rev[maxn],n,m,cur[maxn],vis[maxn],d[maxn],a,b,c;
void addEdge(int i,int a,int b,int c,int d)
{
    u[i]=a;v[i]=b;w[i]=c;rev[i]=d;
    next[i]=first[a];first[a]=i;
}
bool bfs(int s,int t)
{
    memset(d,42,sizeof(d));
    memset(vis,0,sizeof(vis));
    Q.push(s);vis[s]=1;d[s]=0;
    while(Q.size())
    {
        int p=Q.front();Q.pop();
        for(int i=first[p];i!=-1;i=next[i])
            if(!vis[v[i]] && w[i]>0)
            {
                vis[v[i]]=1;
                d[v[i]]=d[p]+1;
                Q.push(v[i]);
            }
    }
    return vis[t];
}
int dfs(int x,int t,int a)
{
    if(x==t || a==0)return a;
    int flow=0,f;
    for(int& i=cur[x];i!=-1;i=next[i])
        if(d[x]+1==d[v[i]] && (f=dfs(v[i],t,min(a,w[i])))>0)
        {
            w[i]-=f;w[rev[i]]+=f;a-=f;flow+=f;
            if(a==0)break;
        }
    return flow;
}
int Dinic(int s,int t)
{
    int flow=0;
    while(bfs(s,t))
    {
        for(int i=1;i<=n;i++)cur[i]=first[i];
        flow+=dfs(s,t,oo);
    }
    return flow;
}
int main()
{
    memset(first,-1,sizeof(first));
    n=read();m=read();
    for(int i=0;i<m;i++)
    {
        a=read();b=read();c=read();
        addEdge(2*i,a,b,c,2*i+1);
        addEdge(2*i+1,b,a,0,2*i);
    }    
    printf("%d",Dinic(1,n));
}

 

posted @ 2016-12-15 20:13  小飞淙的云端  阅读(260)  评论(0编辑  收藏  举报