/*
网络流最短增广路算法
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define oo 0x3f3f3f3f
using namespace std;
const int maxn = 1010;
struct node
{
int c,f;
};
int n,m;
node mp[maxn][maxn];
int level[maxn];
int last[maxn][maxn];
int que[maxn*1000],qs,qe;
int vis[maxn], par[maxn],add[maxn];
void BuildRemain(int s, int t)//构造剩余网络
{
memset(level, -1, sizeof(level));
memset(last, oo, sizeof(last));
for(int i = 1; i<= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(mp[i][j].c!=oo)
{
if(mp[i][j].c-mp[i][j].f>0)
last[i][j] = mp[i][j].c-mp[i][j].f;
if(mp[i][j].f>0)
last[j][i] = mp[i][j].f;
}
}
}
qs = qe = 0;
que[qs++] = s;
level[s] = 0;
while(qe<qs)//标号分层是对残余网络
{
int u = que[qe++];
for(int i = 1; i <= n; i++)
{
if(level[i]==-1&&last[u][i]!=oo)
{
level[i] = level[u]+1;
que[qs++] = i;
}
}
}
}
int FindBfs(int s, int t)
{
memset(vis, 0,sizeof(vis));
memset(par, 0,sizeof(par));
memset(add, 0,sizeof(add));
vis[s] = 1;
par[s] = 0;
add[s] = oo;
qs = qe = 0;
que[qs++] = s;
while(qe<qs&&!vis[t])
{
int u = que[qe++];
for(int i = 1; i <= n; i++)
{
if(!vis[i]&&last[u][i]!=oo&&level[i]==level[u]+1)
{
vis[i] = 1;
par[i] = u;
add[i] = min(add[u], last[u][i]);
que[qs++] = i;
}
}
}
if(!vis[t]||add[t]==0)return 0;
return 1;
}
void Zdzgl(int s,int t)
{
int flag = 0;
while(1)
{
/*(1)构造残留网络*/
BuildRemain(s,t);
/*(2)构造层次网络,寻找增广路*/
flag = 0;
while(FindBfs(s,t))
{
flag = 1;
int u = par[t],v=t;
int a = add[t];
while(u!=0)
{
if(mp[u][v].c!=oo)
mp[u][v].f += a;
else
mp[v][u].f -= a;
last[u][v]-=a;
if(last[u][v]==0)last[u][v] = oo;
v = u;
u = par[v];
}
}
if(!flag)break;
}
int Maxflow = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(i == 1 && mp[i][j].f!=oo)
Maxflow += mp[i][j].f;
if(mp[i][j].f != oo)
printf("%d-->%d: %d\n",i,j,mp[i][j].f);
}
}
printf("MaxFlow:%d\n",Maxflow);
}
int main()
{
int u,v,c,f;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
mp[i][j].c = mp[i][j].f = oo;
}
}
for(int i = 0; i < m; i++)
{
scanf("%d%d%d%d",&u,&v,&c,&f);
mp[u][v].c = c;
mp[u][v].f = f;
}
Zdzgl(1,n);
}
return 0;
}
/*
7 12
1 2 4 3
1 3 10 3
2 3 1 1
2 5 7 2
2 4 2 0
3 4 5 1
3 6 3 3
4 5 6 0
4 6 1 1
5 7 9 2
6 5 5 0
6 7 6 4
*/
最大流算法_最短增广算法
最新推荐文章于 2021-10-05 00:21:37 发布