网络最大流增广路模板(EK & Dinic)

EK算法:

int fir[maxn];
int u[maxm],v[maxm],cap[maxm],flow[maxm],nex[maxm];
int e_max;
int p[maxn],q[maxn],d[maxn];

void add_edge(int _u,int _v,int _w)
{
    int e;
    e=e_max++;
    u[e]=_u;v[e]=_v;cap[e]=_w;
    nex[e]=fir[u[e]];fir[u[e]]=e;
    e=e_max++;
    u[e]=_v;v[e]=_u;cap[e]=0;
    nex[e]=fir[u[e]];fir[u[e]]=e;
}

int max_flow(int s,int t)
{
    memset(flow,0,sizeof flow);
    int total_flow=0;

    for (;;)
    {
        memset(d,0,sizeof d);
        d[s]=INF;
        int f=0,r=0;
        q[0]=s;
        while (f<=r)
        {
            int _u=q[f++];
            for (int e=fir[_u];~e;e=nex[e])
            {
                if (!d[v[e]] && cap[e]>flow[e])
                {
                    q[++r]=v[e];
                    p[v[e]]=e;
                    d[v[e]]=min(d[u[e]],cap[e]-flow[e]);
                }
            }
        }

        if (d[t]==0) break;

        for (int e=p[t];;e=p[u[e]])
        {
            flow[e]+=d[t];
            flow[e^1]-=d[t];
            if (u[e]==s) break;
        }

        total_flow+=d[t];
    }

    return total_flow;
}

Dinic算法(效率远高于EK算法):

int fir[maxn];
int u[maxm],v[maxm],cap[maxm],flow[maxm],nex[maxm];
int e_max;
int iter[maxn],q[maxn],lv[maxn];

void add_edge(int _u,int _v,int _w)
{
    int e;
    e=e_max++;
    u[e]=_u;v[e]=_v;cap[e]=_w;
    nex[e]=fir[u[e]];fir[u[e]]=e;
    e=e_max++;
    u[e]=_v;v[e]=_u;cap[e]=0;
    nex[e]=fir[u[e]];fir[u[e]]=e;
}

void dinic_bfs(int s)
{
    int f,r;
    memset(lv,-1,sizeof lv);
    q[f=r=0]=s;
    lv[s]=0;
    while(f<=r)
    {
        int x=q[f++];
        for (int e=fir[x];~e;e=nex[e])
        {
            if (cap[e]>flow[e] && lv[v[e]]<0)
            {
                lv[v[e]]=lv[u[e]]+1;
                q[++r]=v[e];
            }
        }
    }
}

int dinic_dfs(int _u,int t,int _f)
{
    if (_u==t)  return _f;
    for (int &e=iter[_u];~e;e=nex[e])
    {
        if (cap[e]>flow[e] && lv[_u]<lv[v[e]])
        {
            int _d=dinic_dfs(v[e],t,min(_f,cap[e]-flow[e]));
            if (_d>0)
            {
                flow[e]+=_d;
                flow[e^1]-=_d;
                return _d;
            }
        }
    }

    return 0;
}

int max_flow(int s,int t)
{

    memset(flow,0,sizeof flow);
    int total_flow=0;

    for (;;)
    {
        dinic_bfs(s);
        if (lv[t]<0)    return total_flow;
        memcpy(iter,fir,sizeof iter);
        int _f;

        while ((_f=dinic_dfs(s,t,INF))>0)
            total_flow+=_f;
    }

    return total_flow;
}

网络最大流增广路模板(EK & Dinic)

时间: 2024-08-01 13:19:57

网络最大流增广路模板(EK & Dinic)的相关文章

最大流——增广路算法

关于网络流的增广路算法,网上有很多详细介绍,这里是摘录的模板.详细请见:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 1 #include<iostream> 2 #include<iomanip> 3 #include<ctime> 4 #include<climits> 5 #include<algorithm> 6 #include<queue>

最大流增广路(KM算法) HDOJ 2255 奔小康赚大钱

题目传送门 1 /* 2 KM:裸题第一道,好像就是hungary的升级版,不好理解,写点注释 3 KM算法用来解决最大权匹配问题: 在一个二分图内,左顶点为X,右顶点为Y,现对于每组左右连接Xi,Yj有权w(i,j), 4 求一种匹配使得所有w(i,j)的和最大.也就是最大权匹配一定是完备匹配.如果两边的点数相等则是完美匹配. 5 如果点数不相等,其实可以虚拟一些点,使得点数相等,也成为了完美匹配.最大权匹配还可以用最大流去解决 6 */ 7 #include <cstdio> 8 #inc

最大流增广路(KM算法) HDOJ 1533 Going Home

题目传送门 1 /* 2 最小费用流:KM算法是求最大流,只要w = -w就可以了,很经典的方法 3 */ 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3f3f; 12 int x

网络流——增广路算法(dinic)模板

1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdio> 6 #include<queue> 7 using namespace std; 8 struct data 9 { 10 int from,to,next,cup,flow; 11 data(){from=-1,to=-1,next=-

最大流增广路(KM算法) HDOJ 1853 Cyclic Tour

题目传送门 1 /* 2 KM: 相比HDOJ_1533,多了重边的处理,还有完美匹配的判定方法 3 */ 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3f3f; 12 int x

关于最短增广路算法和连续最短增广路算法的操作步骤

最短增广路算法(SAP): 1.初始化容量网络和网络流: 2.构造残留网络和层次网络,如果汇点不在层次网络中,则算法结束: 3.在层次网络中不断用BFS增广,直到层次网络中没有增广路为止:每次增广完毕,在层次网络中要去掉因改进流量而导致饱和的弧: 4.转到步骤(2). 连续最短增广路算法(Dinic): 1.初始化容量网络和网络流: 2.构造残留网络和层次网络,如果汇点不在层次网络中,则算法结束: 3.在层次网络中用一次DFS过程进行增广,DFS执行完毕,该阶段的增广也执行完毕: 4.转到步骤(

Drainage Ditches(最大流基础_增广路算法)

 Drainage DitchesCrawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover p

Power Network(最大流基础_增广路算法:多源多汇,自建总源点和总汇点)

 Power NetworkCrawling in process... Crawling failed Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description A power network consists of nodes (power stations, consumers and dispatchers) connected by p

增广路算法

#include<queue> #include<cstdio> #include<iostream> #include<cstring> using namespace std; const int maxn = 20; const int INF = (1<<30); int cap[maxn][maxn],flow[maxn][maxn];//cap记录容量,flow记录流量 int m; //弧的数量 int EdmondsKarp(in