HDU 3549 Flow Problem (网络流入门+模板详解)

来源:互联网 发布:手机淘宝看注册时间 编辑:程序博客网 时间:2024/05/20 15:41

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

分析:做的第一道网络流题、EK算法感觉挺不错的、除了最开始的时候添加反向边比较费解一点别的都比较容易理解、好了、不多说了、反正一道经典的网络流入门题被AC了、再切一些题继续学习更高效的预流推进法、加油!

#include<stdio.h>#include<string.h>#include<queue>#include<iostream>using namespace std;#define INF 0x7fffffff#define MAXN 20int map[MAXN][MAXN];int vis[MAXN];int pre[MAXN];//记录走过的路径int m,n;int bfs(int s,int t){    queue<int > q;    memset(pre,-1,sizeof(pre));    memset(vis,0,sizeof(vis));    pre[s]=s;    vis[s]=1;    q.push(s);    while(!q.empty()){        int now=q.front();        q.pop();        for(int i=1;i<=n;i++){//遍历出一条能走增广路            if(map[now][i]&&!vis[i]){                pre[i]=now;//记录前一条边、好寻找路径                vis[i]=1;                if(i==t)return 1;//找到了一条增广路                q.push(i);            }        }    }    return 0;//找不到增广路了}int EK(int s,int t){    int flow=0,d,i;    while(bfs(s,t)){//当能找到一条增广路的时候        d=INF;        for(i=t;i!=s;i=pre[i]){//从终点回溯到起点、寻找流量最小的边            if(d>=map[pre[i]][i])                d=map[pre[i]][i];        }        for(i=t;i!=s;i=pre[i]){//找到最小流量后正向边流量减少、反向变流量增加            map[pre[i]][i]-=d;            map[i][pre[i]]+=d;//EK算法就精髓所在、利用流守恒原理、用反向边代替路径回溯        }        flow+=d;//不断增加流量    }    return flow;}int main(){    int t,k=1;    scanf("%d",&t);    while(t--){        memset(map,0,sizeof(map));        scanf("%d%d",&n,&m);        int s,e,v;        for(int i=1;i<=m;i++){            scanf("%d%d%d",&s,&e,&v);            map[s][e]+=v;//防止重边的情况        }        printf("Case %d: %d\n",k,EK(1,n));        k++;    }    return 0;}