#include <cstdio>
#include <algorithm>
#include <queue>
#include<iostream>
#include <string.h>
using namespace std;
using namespace std;
int const MAX = 1005;
int const inf = 0x3f3f3f3f;
int c[MAX][MAX];//c[u][v]保存容量
int f[MAX][MAX];//f[u][v]保存当前流量
int a[MAX];// a数组在每趟bfs中找到最小路径中最小残余流量的,a数组使个递推数组,a[v]的意思是从源点s到点v的最小残余流量
int p[MAX];//保存前一个点
int n, m;
int bfs(int s, int t)
{
queue<int> q;
int flow = 0;
while(!q.empty()) q.pop();
memset(f, 0, sizeof(f));
while(1){
memset(a, 0, sizeof(a));
a[s] = inf;//将起始点的最小残余量设为最大
q.push(s);
while(!q.empty()){//bfs找到一条最短路,这里的边不代表距离,可以看作每两个点都是单位距离的
int u;
u = q.front();
q.pop();
for(int v = 1; v <= m; v++){//枚举所有点v <u,v>
if(!a[v] && c[u][v] > f[u][v]){//a[]可以代替vis[],来判断这个点是否已经遍历过,后面那个条件更是起了关键作用,很巧妙
p[v] = u;
q.push(v);
a[v] = min(a[u], c[u][v] - f[u][v]);//递推
}
}
}
if(!a[t]) break;//直到最小残余流量为0时,退出
for(int u = t; u != s; u = p[u]){
f[p[u]][u] += a[t];
f[u][p[u]] -= a[t];
}
flow += a[t];
}
return flow;
}
int main()
{
while(~scanf("%d %d", &n, &m)){
memset(c, 0, sizeof(c));
memset(p, 0, sizeof(p));
for(int i = 1; i <= n; i++){
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
c[u][v] += w;
}
printf("%d\n", bfs(1, m));
}
return 0;
}
网络流
最新推荐文章于 2024-08-05 23:05:49 发布