最大流模板题目
Ford-Fulkerson:
#include <stdio.h>
#include <string.h>
#define N 202
int q[N];//用于找增广路径的队列
int c[N][N],f[N][N];//c是路径的容量,f保存寻找过程中的流量
int a[N],p[N];//p存放一条增广路径的前一个结点
int n,m;
int maxflow(int s,int t){//从s到t的最大流
int i,j,res = 0;
int front,rear;
while(1){
front = rear = -1;
q[++rear] = s;
memset(a,0,sizeof(a));
memset(p,0,sizeof(p));
a[s] = 0x3fffffff;
while(front < rear){
i = q[++front];
for(j = 1;j<=n;j++)
if(!a[j] && c[i][j]-f[i][j]>0){
a[j] = a[i]<c[i][j]-f[i][j]?a[i]:c[i][j]-f[i][j];
q[++rear] = j;
p[j] = i;
}
}
if(!a[t])
break;
for(j = t;j!=s;j=p[j]){
f[p[j]][j] += a[t];
f[j][p[j]] -= a[t];
}
res += a[t];
}
return res;
}
int main(){
freopen("a.txt","r",stdin);
while(scanf("%d %d",&m,&n)!=EOF){
int i,x,y,w;
memset(c,0,sizeof(c));
memset(f,0,sizeof(f));
for(i = 0;i<m;i++){
scanf("%d %d %d",&x,&y,&w);
c[x][y] += w;
}
printf("%d\n",maxflow(1,n));
}
return 0;
}
当残余网络的分层操作无法算出汇点的层次(即BFS到达不了汇点)时,算法结束,最大流求出。一般用栈实现DFS,这样就能从栈中提取出增广路径。
#include <stdio.h>
#include <string.h>
#define INF 0x3fffffff
#define min(a,b) a<b?a:b
#define N 205
int n,m;
int flow[N][N],visited[N],layer[N],q[N],stack[N];
int do_layer(int s,int t){//用队列对节点进行分层
int i,front,rear,now;
front = rear = -1;
memset(layer,-1,sizeof(layer));
q[++rear] = s;
layer[s] = 0;
while(front < rear){
now = q[++front];
for(i = s;i<=t;i++)
if(layer[i]==-1 && flow[now][i]>0){
layer[i] = layer[now]+1;
if(i == t)
return 1;
q[++rear] = i;
}
}
return 0;
}
int dinic(int s,int t){//用堆栈模拟dfs
int i,now,top=-1,aug,res=0,temp,vs,vt;
while(do_layer(s,t)){
memset(visited,0,sizeof(visited));
stack[++top] = s;
visited[s] = 1;
while(top>-1){
now = stack[top];
if(now == t){
aug = INF;temp = 0;//temp保存回溯的位置
for(i = 1;i<=top;i++){//找本次增广的流量
vs = stack[i-1];
vt = stack[i];
if(aug>flow[vs][vt] && flow[vs][vt]>0){
aug = min(aug,flow[vs][vt]);
temp = vs;
}
}
res += aug;
for(i = 1;i<=top;i++){//更新流量以及反向边
vs = stack[i-1];
vt = stack[i];
flow[vs][vt] -= aug;
flow[vt][vs] += aug;
}
while(stack[top]!=temp){
visited[stack[top]] = 0;
top--;
}
}else{
for(i = s;i<=t;i++)
if(!visited[i] && flow[now][i]>0 && layer[i]==layer[now]+1){
stack[++top] = i;
visited[i] = 1;
break;
}
if(i > t)
top--;
}
}
}
return res;
}
int main(){
freopen("a.txt","r",stdin);
while(scanf("%d %d",&m,&n)!=EOF){
int i,a,b,w;;
memset(flow,0,sizeof(flow));
for(i = 0;i<m;i++){
scanf("%d %d %d",&a,&b,&w);
flow[a][b] += w;
}
printf("%d\n",dinic(1,n));
}
return 0;
}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ovod.cn 版权所有 湘ICP备2023023988号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务