HDU 1532 Drainage Ditches(网络流模板题)

题目大意:就是由于下大雨的时候约翰的农场就会被雨水给淹没,无奈下约翰不得不修建水沟,而且是网络水沟,并且聪明的约翰还控制了水的流速,

本题就是让你求出最大流速,无疑要运用到求最大流了。题中m为水沟数,n为水沟的顶点,接下来Si,Ei,Ci分别是水沟的起点,终点以及其容量。求源点1到终点m的最大流速。

EK算法详解参考链接

EK模板

#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
#define MaxInt 0x3f3f3f3f

using namespace std;

int m,n,f[210][210],cap[210][210],a[210],p[210];
queue<int> que;
int Edmond_Karp(int s,int t)
{
  int flow=0;
  while(1){//BFS找增广路
    memset(a,0,sizeof(a));
    a[s]=MaxInt;
    que.push(s);
    while(!que.empty()){
      int u=que.front();
      que.pop();
      for(int v=1;v<=m;v++){//m为节点个数
        if(!a[v]&&cap[u][v]>f[u][v]){
          p[v]=u;//记录v的前驱
          que.push(v);
          a[v]=min(a[u],cap[u][v]-f[u][v]);//a[v]为s-v路径上的最小流量
        }
      }
    }
    if(a[t]==0) break;//找不到,则当前已是最大流量
    for(int v=t;v!=s;v=p[v])//从汇点往回走
    {
      f[p[v]][v]+=a[t];//更新正向流量
      f[v][p[v]]-=a[t];//更新反向流量
    }
    flow+=a[t];//更新从s流出的总流量
  }
  return flow;
}

int main()
{
  int u,v,i,c,ans;
  while(scanf("%d%d",&n,&m)!=EOF){
    memset(cap,0,sizeof(cap));
    memset(f,0,sizeof(f));
    for(i=1;i<=n;i++){
      scanf("%d%d%d",&u,&v,&c);
      cap[u][v]+=c;//注意重边
    }
    ans=Edmond_Karp(1,m);
    printf("%d\n",ans);
  }
  return 0;
}

 Dinic模板

#include<cstdio>  
#include<queue>
#include<cstring>
using namespace std;  
#define inf 0x7fffffff  
#define min(a,b) a<b?a:b  
int n,m,u,v,w;  
int level[210];  
struct Dinic  
{  
    int cap;  
    int flow;  
}edge[210][210];  
//构造层次网络 
bool Dinic_bfs(int s,int t) 
{  
    queue<int> que;  
    memset(level,0,sizeof(level));//初始化所有顶点的层次为 0  
    que.push(s);  
    level[s]=1;  
    while(!que.empty()){  
        int u=que.front();  
        que.pop();  
        for(int v=1;v<=m;v++){//即顶点v未被访问过,只考虑残量网络中顶点u,v是否存在边 
            if(!level[v]&&edge[u][v].flow<edge[u][v].cap){  
                level[v]=level[u]+1;  
                que.push(v);  
            }  
        }  
    }   
    return level[t]; 
}
//u为当前节点,a为当前最小残量进行多路增广   
int Dinic_dfs(int u,int a) 
{  
    int flow=0;  
    if(u==m||a==0)  
        return a;
    for(int v=1;v<=m;v++){  
        if(level[u]+1==level[v]){  
            if(edge[u][v].cap>edge[u][v].flow){  
                int r=Dinic_dfs(v,min(a,edge[u][v].cap-edge[u][v].flow));  
                edge[u][v].flow+=r;  
                edge[v][u].flow-=r;  
                a-=r,flow+=r;  
            }  
        }  
    }  
    return flow;  
} 
//求出最大流 
int Dinic()  
{  
    int flow=0;   
    while(Dinic_bfs(1,m)) 
        flow+=Dinic_dfs(1,inf);  
    return flow;  
}  
int main()  
{  
    while(scanf("%d%d",&n,&m)!=EOF){  
        memset(edge,0,sizeof(edge));  
        for(int i=1;i<=n;i++){  
            scanf("%d%d%d",&u,&v,&w);  
            edge[u][v].cap+=w;//防止重边  
        }  
        printf("%d\n",Dinic());  
    }  
    return 0;  
}  

 

posted @ 2017-01-19 18:03  despair_ghost  阅读(175)  评论(0编辑  收藏  举报