我在写网络流时经常被卡常(悲),几乎可以说是用上了大部分的卡常技巧了,可还是有几个题卡不过去(p4480就是你
可是,就在刚刚,做p4001时我又被卡了,但我到讨论区一看,发现一个逆天的玄学优化
如下
未修改前
ll dinic(int u,ll flow){
ll zy=0;vis[u]=1;
if(u==t)return flow;
for(int i=head[u];i&&flow;i=nxt[i]){
int v=to[i];head[u]=i;
if(w[i]&&d[v]==d[u]+c[i]&&(!vis[v]||v==t)){
ll jb=dinic(v,min((ll)w[i],flow));
zy+=jb;w[i]-=jb;w[i^1]+=jb;
ans+=jb*c[i];flow-=jb;
//注意此处
}
}
vis[u]=0;
return zy;
}
修改后
ll dinic(int u,ll flow){
ll zy=0;vis[u]=1;
if(u==t)return flow;
for(int i=head[u];i&&flow;i=nxt[i]){
int v=to[i];head[u]=i;
if(w[i]&&d[v]==d[u]+c[i]&&(!vis[v]||v==t)){
ll jb=dinic(v,min((ll)w[i],flow));
zy+=jb;w[i]-=jb;w[i^1]+=jb;
ans+=jb*c[i];flow-=jb;
if(!flow)break;//看这里
}
}
vis[u]=0;
return zy;
}
这个小小的改动直接让我从T的苦海中解脱,把包括p4480内的众多积攒下来被卡了的题过了
具体原因我想了想(看了看别人的解释,应该与当前弧优化有关,感性理解如下
当我们不加这段话,当前弧可能会指向下一条边,如果这条边还有残量的话,就需要再跑一次dinic过程,导致时间会多出来一截
感谢苍天让我发现了这个玄学优化