POJ 1273 Drainage Ditches(网络流dinic算法模板)

POJ 1273
给出M条边,N个点,求源点1到汇点N的最大流量。

 

本文主要就是附上dinic的模板,供以后参考。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <string.h>

/*
POJ 1273
dinic算法模板

边是有向的,而且存在重边,且这里重边不是取MAX,而是累加和
*/
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=201;
int pri[maxn];
long long sum; //计算总流量
int s,t; //s:源点 t:汇点
int n,m;

struct Edge{
    int c,f;
}maps[maxn][maxn];

int min(int a,int b){
    return a<b?a:b;
}
//每次先BFS,看看是否存在从源点到汇点的增广路
bool BFS() {
    queue<int> q;
    memset(pri,0,sizeof(pri));
    pri[1]=1;
    q.push(1);
    while(!q.empty()) {
        int temp=q.front();
        q.pop();
        for(int i=1; i<=m; i++) {
            if(!pri[i] && maps[temp][i].c-maps[temp][i].f){
                pri[i]=pri[temp]+1;
                if(i==t)
                    return true;    //即如果可以流到汇点,直接return true
                q.push(i);
            }
        }
    }
    //if(pri[m]>0)
    //    return true;
    return false;
}

//p表示当前节点,flow表示该节点通过的流量
int dinic(int p,int flow){
    if(p==t){
        return flow;
    }
    int f=flow;
    //int value=0;
    for(int i=1;i<=m;i++){
        if(pri[i]==pri[p]+1 && maps[p][i].c-maps[p][i].f){
            int a=maps[p][i].c-maps[p][i].f;  //a为该边可以增加的流量
            int ff=dinic(i,min(a,flow));  //ff为路径中所有a的最小值,即为该条路中可以增加的流量
            maps[p][i].f+=ff;       //正向边
            maps[i][p].f-=ff;       //逆向边
            //value+=ff;
            flow-=ff;
            if(flow<=0)
                break; //优化剪枝
        }
    }
    //return value;
    if(f-flow<=0)
        pri[p]=0;//如果从p点流出去的流量<=0,那么设置pri[p]的值为0,之后在dinic中就不考虑到p点的情况了。
    return f-flow;
}
void init(){
    for(int i=1;i<=m;i++){
        for(int j=1;j<=m;j++){
            maps[i][j].c=maps[i][j].f=0;
        }
    }
}
int main() {
    int a,b,c;
    s=1;
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        //memset(maps,0,sizeof(maps));
        sum=0;
        t=m;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&a,&b,&c);
            maps[a][b].c+=c;    //该题有重边,这里要+=,不是去max
        }
        while(BFS()){
            sum+=dinic(s,INF);
        }
        printf("%I64d\n",sum);
    }
    return 0;
}
View Code

 

再给出一个大牛的模板:

#include <cstdio>
#include <queue>

using namespace std;

typedef int LL;
const int N = 205;
const int M = N << 2;
const int INF = (int)1e9;

struct Dinic {

    struct Edge {
        int v;
        LL cap, flow;
        Edge* next, * pair;

        void init(int a, LL b, Edge* e1, Edge* e2) {
            v = a, cap = b, flow = 0, next = e1, pair = e2;
        }    
    };

    Edge* head[N], * used[N];
    Edge* it;
    int lev[N], que[N];
    Edge E[M];
    int n, s, t;
    LL maxFlow;

    void init(int n, int s, int t) {
        it = E;
        this->n = n;
        this->s = s, this->t = t;
        for (int i = 0; i < n; i++)
            head[i] = 0;
    }

    void add(int u, int v, LL c) {
        it->init(v, c, head[u], it + 1);
        head[u] = it++;
        it->init(u, 0, head[v], it - 1);
        head[v] = it++;
    }

    bool bfs() {
        for (int i = 0; i < n; lev[i++] = -1);
        lev[s] = 0;
        int st = 0, ed = 0;
        que[ed++] = s;
        while (st < ed) {
            int u = que[st++];
            for (Edge* e = head[u]; e;  e = e->next) {
                int v = e->v;
                if (lev[v] == -1 && e->cap > e->flow) {
                    lev[v] = lev[u] + 1;
                    que[ed++] = v;
                }
            }
        }
        return lev[t] != -1;    
    }

    LL dfs(int u, LL f) {
        if (u == t) return f;
        for (Edge* & e = used[u]; e; e = e->next) {
            int v = e->v;
            if (e->cap > e->flow && lev[v] == lev[u] + 1) {
                LL tmp = dfs(v, min(e->cap - e->flow, f));
                if (tmp > 0) {
                    e->flow += tmp;
                    e->pair->flow -= tmp;
                    return tmp;
                }
            }
        }
        return 0;
    }

    void run() {
        maxFlow = 0;
        while (bfs()) {    
            for (int i = 0; i < n; i++)
                used[i] = head[i];
            LL f = 1;
            while (f) {
                f = dfs(s, INF);
                maxFlow += f;
            }
        }
    }

}G;

int main() {
    int n, m, u, v, w;
    while (~scanf("%d%d", &m, &n)) {
        G.init(n, 0, n - 1);
        while (m--) {
            scanf("%d%d%d", &u, &v, &w);
            G.add(u - 1, v - 1, w);
        }
        G.run();
        printf("%d\n", G.maxFlow);
    }
    return 0;
}
View Code

 

posted @ 2015-05-19 10:14  辰曦~文若  阅读(243)  评论(0编辑  收藏  举报