最大流
最大流
简要题意:
自来水厂(源点)要把水送到
保证每户人家都有一条从源点到汇点的路径经过
图上每条水管都有一定的容量
请问自来水厂怎样才能使输水效率最高?
先了解几个定义:
流网络
流网络
流网络中有两个特殊的顶点: 源点
假定每个顶点都处于从源点到汇点的某条路径上,就是说,对每个顶点
G为连通图,且
边的流是一个实值函数f,满足下列三个性质:
1、容量限制:对所有
理解:流量不会超过边的容量
2、反对称性:对所有
理解:一个方向的流是其反方向流的相反数
3、流守恒性:对所有
理解:进入点u的总流量=离开点u的总流量
残留网络
边的残留容量:
残留网络:给定一流网络
其中
这就是说,在残留网络中,每条边(称为残留边)能够容纳一个严格为正的网络流
当
此时边(u,v)在残留网络中。
朴素做法(Ford-Fulkerson算法):
做法
每次从源点开始找到一条路径(边的容量不为0)到汇点,更新这条路径的剩余
1、将
2、
如果找不到就结束。
局限分析
如图所示的流网络,M非常大,例如10^10。在寻找增广路时不幸按红色所示线路,那么就会不断便利边
距离标号
数组
每次
如果
code
#include<bits/stdc++.h>
using namespace std;
const int N=205;
int n , vd[N] , d[N] , s , t , m , u , v;
long long mp[N][N] , wi;
long long dfs(int x , long long past) {
if(x == t)
return past;
long long del = 0 , now = past;
int mind = n - 1;
for(int i = 1 ; i <= n ; i++) {
if(!mp[x][i])
continue;
if(d[x] == d[i] + 1) {
del = min(mp[x][i] , now);
del = dfs(i , del);
now -= del;
mp[x][i] -= del;
mp[i][x] += del;
if(d[s] >= n)
return past - now;
if(now == 0)
break;
}
mind = min(mind , d[i]);
}
if(now == past) {
vd[d[x]] --;
if(!vd[d[x]])
d[s] = n;
d[x] = mind + 1;
vd[d[x]] ++;
}
return past - now;
}
void flow() {
long long ans = 0;
vd[0] = n;
while(d[s] < n) {
ans += dfs(s , 100000000000000000);
}
printf("%lld" , ans);
}
int main() {
scanf("%d%d%d%d" , &n , &m , &s , &t);
for(int i = 1 ; i <= m ; i++) {
scanf("%d%d%d" , &u , &v , &wi);
mp[u][v] += wi;
}
flow();
return 0;
}
如果人生会有很长,愿有你的荣耀永不散场
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?