【模板】网络最大流
终于过了这个奇怪的网络流了。一直感觉那个什么Dinic算法很奇怪,还要什么bfs分层,今天花了一下午的时间终于搞懂了Dinic是什么鬼。
Dinic是一个求解网络最大流的算法。我目前所掌握的只是小优化版本的Dinic,至于数据加强版我过不了(太弱了)。这个算法和前面二分图最大匹配算法是一个内核,都是在思考假如我们已经有一个方案了,如何在不破坏这个方案的基础上尽量多地塞新的元素进去(新的元素就是所谓的增广路)。二分图上增广路是一个交错杂居的路径,而网络流中的增广路是一条从S到T的一个流量不为0的合法轨迹。如何求解?首先可以使用朴素的想法,假如我们已经有一个网络流了(或者叫做残量网络流),思考如何能找寻一条增广路呢?有两种途径。一是自己开辟一条新的道路通向汇点,另一种是让其它道路的流量滚回去,空出来的流量自己填上。第一种很好思考,第二种应该怎么办呢?思考一下,对比一下添加这条增广路前后这个网络的变化有哪些。很明显原先那条被占的路上的流量不会有变化,变化的是挨了打之后重新寻找出路的那股旧流开辟的道路罢了。既然变化量只有那个,那么完全可以把这个过程看成是当前增广路在开辟新天地,实现上只需要建反向边就可以了。
讲解里那些术语把我搞蒙了,不就是那个意思吗。
有个bfs对朴素算法的优化。为什么我不知道,但确实可以优化朴素的Dinic。另外这里一定要手写一个队列,用std会死得很难看。代码层面,bfs很简单不说,dfs就是枚举出边,验证层数关系,累加流量即可。
#include<cstdio>
#include<cstring>
//#define zczc
#define int long long
using namespace std;
const int N=210;
const int M=5010;
const int inf=1e12;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int min(int s1,int s2){
return s1<s2?s1:s2;
}
int m,n,s,t;
struct edge{
int t,v,next;
}e[M<<1];
int head[N],esum=1;
inline void add(int fr,int to,int val){
esum++;e[esum].t=to;e[esum].v=val;e[esum].next=head[fr];
head[fr]=esum;return;
}
int d[N],q[N],l,r;
bool bfs(){
memset(d,0,sizeof(int)*(m+1));
q[l=r=1]=s,d[s]=1;
while(l<=r){
int now=q[l++];
for(int i=head[now],th;i;i=e[i].next){
if(e[i].v&&d[th=e[i].t]==0)d[th]=d[now]+1,q[++r]=th;
}
}
return d[t]>0;
}
int dfs(int wh,int val){
if(wh==t)return val;int cost=0;
for(int i=head[wh],th;i;i=e[i].next){
if(e[i].v==0||d[th=e[i].t]!=d[wh]+1)continue;
int now=dfs(th,min(val,e[i].v));
e[i].v-=now,e[i^1].v+=now,val-=now,cost+=now;
}
return d[wh]=cost==0?0:d[wh],cost;
}
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
int s1,s2,s3;
read(m);read(n);read(s);read(t);
for(int i=1;i<=n;i++){
read(s1);read(s2);read(s3);
add(s1,s2,s3);add(s2,s1,0);
}
int ans=0;
while(bfs())ans+=dfs(s,inf);
printf("%lld",ans);
return 0;
}
update.2022.02.08
check函数压行版
bool check(){
memset(d,0,sizeof(d));q[l=r=1]=s;d[s]=1;int wh;
while(l<=r)
for(int i=head[wh=q[l++]],th;i;i=e[i].next)
if(e[i].v!=0&&d[th=e[i].t]==0)q[++r]=th,d[th]=d[wh]+1;
return d[t];
}
一如既往,万事胜意
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App