网络流dinic非当前弧优化提高代码效率的语句
在看了网上许多的dinic跑最大流的教程后,发现同样是dinic,都没有经过当前弧优化,但是有些代码的效率是另外一些代码的。
不过其实原因很简单的,归根结底还是出在bfs和dfs上。
下面来看在同一题 洛谷P1361 小M的作物 下的两份代码的bfs和dfs:
网上常见的一种dinic模板
int bfs()
{
queue<int> q;
memset(dep,-1,sizeof(dep));
dep[S]=0;
q.push(S);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(edge[i].w>0&&dep[v]==-1)
{
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return dep[T]!=-1;
}
int dfs(int u,int flow)
{
if(u==T)return flow;
int f=0,d=0,v;
for(int i=head[u];i;i=edge[i].nxt)
{
v=edge[i].to;
if(dep[u]+1==dep[v]&&edge[i].w>0)
{
d=dfs(v,min(flow,edge[i].w));
if(!d)continue;
f+=d;
flow-=d;
edge[i].w-=d;
edge[i^1].w+=d;
if(flow<=0)break;
}
}
return f;
}
很可惜的是,网上这份比较常见的模板T了。
对dinic稍微修改
int bfs()
{
queue<int> q;
memset(dep,-1,sizeof(dep));
dep[S]=0;
q.push(S);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(edge[i].w>0&&dep[v]==-1)
{
dep[v]=dep[u]+1;
q.push(v);
if(v==T)return 1;//1.在添加此语句后,当终点的层次被划分好即可返回
}
}
}
return dep[T]!=-1;
}
int dfs(int u,int flow)
{
if(u==T)return flow;
int f=0,d=0,v;
for(int i=head[u];i;i=edge[i].nxt)
{
v=edge[i].to;
if(dep[u]+1==dep[v]&&edge[i].w>0)
{
d=dfs(v,min(flow,edge[i].w));
if(!d)continue;
f+=d;
flow-=d;
edge[i].w-=d;
edge[i^1].w+=d;
if(flow<=0)break;
}
}
if(f==0)dep[u]=-1;//2.添加此语句,表明该处已无流量,以后都不需再遍历
return fl;
}
仅添加1语句的效率:
可见仍然会TLE
仅添加2语句的效率:
可以看到此时已经大大提升了代码的运行效率
1、2语句同时添加的效率:
相比仅添加2语句,两个语句同时添加的速度要更快
以上就是我在学习最大流时所发现的问题,仅供参考,不对之处还望指出。