HDU 1532 Drainage Ditches(网络流模板题)
题目大意:就是由于下大雨的时候约翰的农场就会被雨水给淹没,无奈下约翰不得不修建水沟,而且是网络水沟,并且聪明的约翰还控制了水的流速,
本题就是让你求出最大流速,无疑要运用到求最大流了。题中m为水沟数,n为水沟的顶点,接下来Si,Ei,Ci分别是水沟的起点,终点以及其容量。求源点1到终点m的最大流速。
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; }