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

相关文章: