POJ 1273 && HDU 1532 Drainage Ditches (Dinic 算法)

转载请注明出处:http://blog.csdn.net/a1dark

分析:Dinic模板题、先比EK算法而言、确实要优化一些、Dinic要比EK难理解一些、用一次DFS代替多次BFS、很神奇的算法、Orz。。。

#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
#include<string.h>
#define N 205
#define INF 0xfffffff
int map[N][N];
int level[N];
int m,n;
int bfs(int s,int t){//对顶点进行标号、找出层次图
    memset(level,0,sizeof(level));
    queue<int > q;
    q.push(s);
    level[s]=1;
    while(!q.empty()){
        int now=q.front();
        q.pop();
        for(int i=1;i<=n;i++){
            if(!level[i]&&map[now][i]>0){
                level[i]=level[now]+1;
                q.push(i);
            }
        }
    }
    return level[n]!=0;//汇点是否在层次图中
}
int dfs(int s,int cp){//在层次图中寻找增广路径进行增广
    int tmp=cp;
    int t;
    if(s==n)return cp;
    for(int i=1;i<=n&&tmp;i++){
        if(level[i]==level[s]+1&&map[s][i]>0){
            t=dfs(i,min(tmp,map[s][i]));
            map[s][i]-=t;
            map[i][s]+=t;
            tmp-=t;
        }
    }
    return cp-tmp;
}
int dinic(){
    int ans=0,flow=0;
    while(bfs(1,n)){//汇点不在层次图中,算法终止
        while(flow=dfs(1,INF))
            ans+=flow;
    }
    return ans;
}
int main(){
    while(scanf("%d%d",&m,&n)!=EOF){
        memset(map,0,sizeof(map));
        int s,e,v;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&s,&e,&v);
            map[s][e]+=v;
        }
        printf("%d\n",dinic());
    }
    return 0;
}


你可能感兴趣的:(ACM,网络流,Dinic算法)