网络最大流最短增广路Dinic算法模板

HDU 3549  Flow Problem

#include<cstdio>

#include<cstring>

#include<string>

#include<cmath>

#include<vector>

#include<queue>

#include<algorithm>

using namespace std;





const int maxn=1000+10;

const int INF=0x7FFFFFFF;



struct Edge { int from,to,cap,flow; };

vector<Edge>edges;

vector<int>G[maxn];

bool vis[maxn];

int d[maxn];

int cur[maxn];

int n,m,s,t;



//求出层次网络

bool BFS()

{

    memset(vis,0,sizeof(vis));

    queue<int>Q;

    Q.push(s);

    d[s]=0;

    vis[s]=1;

    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];

}





//加边

void AddEdge(int from,int to,int cap)

{

    Edge r;

    r.from=from;r.to=to;r.cap=cap;r.flow=0;

    edges.push_back(r);

    Edge d;

    d.from=to;d.to=from;d.cap=0;d.flow=0;

    edges.push_back(d);

    m=edges.size();

    G[from].push_back(m-2);

    G[to].push_back(m-1);

}



//每个阶段来一次DFS增广

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 ss,int tt)

{

    int flow=0;

    while(BFS())

    {

        memset(cur,0,sizeof(cur));

        flow+=DFS(ss,INF);

    }

    return flow;

}



//输入输出

int main()

{

    int T,ii;

    scanf("%d",&T);

    for(ii=1;ii<=T;ii++)

    {

        edges.clear();

        for(int i=0;i<maxn;i++) G[i].clear();

        int mm;

        scanf("%d%d",&n,&mm);

        s=1;t=n;//设置源点和汇点

        while(mm--)

        {

            int uu,vv,cc;

            scanf("%d%d%d",&uu,&vv,&cc);

            AddEdge(uu,vv,cc);

        }

        printf("Case %d: %d\n",ii,Maxflow(s,t));

    }

    return 0;

}

 

你可能感兴趣的:(dinic)