【网络流#3】hdu 1532 - Dinic模板题

输入为m,n表示m条边,n个结点

记下来m行,每行三个数,x,y,c表示x到y的边流量最大为c

这道题的模板来自于网络

http://blog.csdn.net/sprintfwater/article/details/7913061

算法时间复杂度o(V^2*E)

 

关于这个模板:
Edge为前向星的边数,所以需要初始化Edge和head数组,其中head数组应初始化为-1

int dinic(int n,int s,int t);
n表示有n个点,这个版无所谓点从0开始还是从1开始,s表示源点,t表示汇点
很好的一个是,这个版的DFS使用的是模拟栈,防止爆栈

#include<cstdio>

#include<cstring>

#include<cmath>

#include<iostream>

#include<algorithm>

#include<set>

#include<map>

#include<stack>

#include<vector>

#include<queue>

#include<string>

#include<sstream>

#define MAXN 200

#define MAXM 400

#define INF (1<<30)

#define eps 0.000001

#define ALL(x) x.begin(),x.end()

#define INS(x) inserter(x,x.begin())

using namespace std;

int i,j,k,n,m,x,y,T,num,w;



const int inf = 0x3f3f3f3f;

struct edgenode

{

    int from,to,next;

    int cap;

}edge[MAXM];

int Edge,head[MAXN],ps[MAXN],dep[MAXN];



void addedge(int x,int y,int c)

{

    edge[Edge].from=x;

    edge[Edge].to=y;

    edge[Edge].cap=c;

    edge[Edge].next=head[x];

    head[x]=Edge++;

    

    edge[Edge].from=y;

    edge[Edge].to=x;

    edge[Edge].cap=0;

    edge[Edge].next=head[y];

    head[y]=Edge++;

}



int dinic(int n,int s,int t)

{

    int tr,flow=0;

    int i,j,k,l,r,top;

    while(1){

        memset(dep,-1,(n+1)*sizeof(int));

        for(l=dep[ps[0]=s]=0,r=1;l!=r;)//BFS部分,将给定图分层 

        {

            for(i=ps[l++],j=head[i];j!=-1;j=edge[j].next)

            {

                if (edge[j].cap&&-1==dep[k=edge[j].to])

                {

                    dep[k]=dep[i]+1;ps[r++]=k;

                    if(k==t)

                    {

                        l=r;

                        break;

                    }

                }

            }

        }

        if(dep[t]==-1)break;

        

        for(i=s,top=0;;)//DFS部分 

        {

            if(i==t)//当前点就是汇点时 

            {

                for(k=0,tr=inf;k<top;++k)

                    if(edge[ps[k]].cap<tr)tr=edge[ps[l=k]].cap;

                    

                for(k=0;k<top;++k)

                    edge[ps[k]].cap-=tr,edge[ps[k]^1].cap+=tr;

                    

                flow+=tr;

                i=edge[ps[top=l]].from;

            }

            

            for(j=head[i];j!=-1;j=edge[j].next)//找当前点所指向的点 

                if(edge[j].cap&&dep[i]+1==dep[edge[j].to]) break;

                

            if(j!=-1)

            {

                ps[top++]=j;//当前点有所指向的点,把这个点加入栈中 

                i=edge[j].to;

            }

            else

            { 

                if (!top) break;//当前点没有指向的点,回溯 

                dep[i]=-1;

                i=edge[ps[--top]].from;

            }

        }

    }

    return flow;

}



int main()

{

    int T,cas,m,s,t,n,maxflow,i;

    int x,y,c;

    double ans;

    while(~scanf("%d%d",&m,&n))

    {   

        memset(head,-1,sizeof(head));

        Edge=0;

        for(i=0;i<m;i++)

        {

            scanf("%d%d%d",&x,&y,&c);

            addedge(x,y,c);

        }

        printf("%d\n",dinic(n,1,n));

    }

    return 0;

}

  

你可能感兴趣的:(dinic)