最大流dinic

Dinic算法的基本思路:
  1. 根据残量网络计算层次图。
  2. 在层次图中使用DFS进行增广直到不存在增广路
  3. 重复以上步骤直到无法增广

 

  1. 用BFS建立分层图  注意:分层图是以当前图为基础建立的,所以要重复建立分层图
  2. 用DFS的方法寻找一条由源点到汇点的路径,获得这条路径的流量I 根据这条路径修改整个图,将所经之处正向边流量减少I,反向边流量增加I,注意I是非负数
  3. 重复步骤2,直到DFS找不到新的路径时,重复步骤1
/****************************************************************************************************

                                        最大流 
                                        dinic算法 
                        

********************************************************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int v[105][105],dis[105];//v是邻接矩阵,dis是bfs时分的层 
int q[2000],l,r;//BFS队列 ,首,尾 
int n;
bool bfs(){
    memset(dis,-1,sizeof(dis));
    dis[1]=0;
    l=0;r=1;
    q[0]=1;
    while(l<r){//队列不为空 
        int j=q[l++];
        for(int i=1;i<=n;i++){
            if(v[j][i]>0&&dis[i]==-1)dis[i]=dis[j]+1,q[r++]=i;
        }
    }
    if(dis[n]>0)return 1;//判断是否能到n 
    return 0;
}
bool dfs(int x,int low){//low为到当前节点最大流 
    int ans=0;
    if(x==n)return low;
    for(int i=1;i<=n;i++){
        if(v[x][i]&&dis[i]==dis[x]+1&&(ans=dfs(i,min(low,v[x][i])))){
            v[x][i]-=ans;v[i][x]+=ans;//边的最大流量更新 
            return ans;
        }
    }
    return ans;
}
int main(){
    int ans=0,tans;
    freopen("maxflowa.in","r",stdin);
    freopen("maxflowa.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)scanf("%d",v[i]+j);
    }
    while(bfs()){//判断是否能到n 
        while(tans=dfs(1,0x7fffffff))ans+=tans;//用增广路更新 
    }
    printf("%d",ans);
    return 0;
} 

 

posted @ 2017-04-20 19:11  Bennettz  阅读(196)  评论(0编辑  收藏  举报