码迷,mamicode.com
首页 > 其他好文 > 详细

网络流模板

时间:2016-04-26 14:16:51      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:

Ford_Fulkerson (O(F*E))


 

感觉不会用到,但还是写一下吧...

复杂度 : 最大流量为 F ,每次最少增广 1 ,最多增广 F 次,每一次最多跑 E 条边(整张图).

 

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define rep(i,n) for(int i=0;i<(n);i++)
#define for1(i,a,n) for(int i=(a);i<=(n);i++)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getnum()
#define print(a) printf("%d",a)
using namespace std;

const int maxn=205,INF=0x7fffffff;
struct edge    { int to,cap,rev; };
int m,n;
bool vis[maxn];
vector <edge> g[maxn];

inline int getnum(){ int r=0,k=1;char c;for(c=getchar();c<0||c>9;c=getchar()) if(c==-) k=-1;for(;c>=0&&c<=9;c=getchar()) r=r*10+c-0; return r*k; }

void add_edge(int from,int to,int cap)
{
    g[from].push_back((edge) { to,cap,g[to].size() });
    g[to].push_back((edge) { from,0,g[from].size()-1 });
}

int dfs(int v,int t,int f)
{
    if(v==t) return f;
    vis[v]=true;
    rep(i,g[v].size())
    {
        edge &e=g[v][i];
        if(!vis[e.to]&&e.cap>0)
        {
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0)
            {
                e.cap-=d;
                g[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

int max_flow(int s,int t)
{
    CC(vis,false);
    int flow=0,f;
    while((f=dfs(s,t,INF))>0)
    {
        flow+=f;
        CC(vis,false);
    }
    return flow;
}

void init()
{
    read(m); read(n);
    for1(i,1,m)
    {
        int from,to,cap;
        read(from); read(to); read(cap);
        add_edge(from,to,cap);
    }
}

int main()
{
    init();
    print(max_flow(1,n));
    return 0;
}
        
        
        
        

 

Dinic (O(E*V^2))


 

复杂度 : 每一张层级图跑完,说明最短增广路要变长了, 重新 bfs 构造新的层级图时最短增广路至少要 +1 ,长度最多为 V - 1 ,所以最多有 ( V - 1 ) 个层级图.在每一个层级图中,每一条增广路都有至少一个瓶颈(路上 cap 最小的弧),跑完这条最短路后这个弧就没有了(因为走了正向所以反向弧不符合 level ,不会在这一张层级图中走了),最多 E 条弧,每次至少消去一条,那最多跑 E 次,每一次最多跑 V 个点,所以在一张层级图里最多跑 E * V 次,综上,总复杂度是O(E*V^2).

 

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;i++)
#define for1(i,a,n) for(int i=(a);i<=(n);i++)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getnum()
#define print(a) printf("%d\n",a)
using namespace std;

const int maxn=205,INF=0x7fffffff;
int m,n;
int iter[maxn],level[maxn];
struct edge { int to,cap,rev; };
vector <edge> g[maxn];

inline int getnum() { int r=0,k=1;char c;for(c=getchar();c<0||c>9;c=getchar()) if(c==--) k=-1;for(;c>=0&&c<=9;c=getchar()) r=r*10+c-0; return r*k; }

void add_edge(int from,int to,int cap)
{
    g[from].push_back((edge) { to,cap,g[to].size() });
    g[to].push_back((edge) { from,0,g[from].size()-1 });
}

void bfs(int s)
{
    CC(level,-1);
    level[s]=1;
    queue <int> q;
    q.push(s);
    while(!q.empty())
    {
        int t=q.front(); q.pop();
        rep(i,g[t].size())
        {
            edge &e=g[t][i];
            if(level[e.to]<0&&e.cap>0)
            {
                level[e.to]=level[t]+1;
                q.push(e.to);
            }
        }
    }
}

int dfs(int v,int t,int f)
{
    if(v==t) return f;
    for(int &i=iter[v];i<g[v].size();i++)
    {
        edge &e=g[v][i];
        if(e.cap>0&&level[v]<level[e.to])
        {
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0)
            {
                e.cap-=d;
                g[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

int max_flow(int s,int t)
{
    int flow=0;
    bfs(s);
    while(level[t]>0)
    {
        CC(iter,0);
        int f;
        while((f=dfs(s,t,INF))>0) flow+=f;
        bfs(s);
    }
    return flow;
}

void init()
{
    read(m); read(n);
    for1(i,1,m)
    {
        int from,to,cap;
        read(from); read(to); read(cap);
        add_edge(from,to,cap);
    }
}

int main()
{
    init();
    print(max_flow(1,n));
    return 0;
}
    
    
    
    
    
    

 


 

网络流模板

标签:

原文地址:http://www.cnblogs.com/Sunnie69/p/5434748.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!