当前位置: 首页 > news >正文

网络流dinic与EK

题目链接:网络流

EK算法核心思想

EK算法是Ford-Fulkerson方法的一种实现,使用BFS来寻找增广路径,用于求解最大流问题

算法步骤:

  1. 初始化

    • 构建残量网络,初始时正向边容量为原容量,反向边容量为0
    • 最大流初始为0
  2. 循环寻找增广路径

    • 使用BFS在残量网络中寻找从源点s到汇点t的路径
    • 记录路径上的最小容量(瓶颈容量)
  3. 更新残量网络

    • 沿着找到的增广路径,正向边减去流量,反向边加上流量
    • 将瓶颈容量加到最大流中
  4. 重复直到找不到增广路径

核心代码:

bool E_K_bfs(){memset(vis,-1,sizeof(vis));pre[s]=-1;vis[s]=1;myline.push(s); minroad[s]=INT_MAX;while(!myline.empty()){int u=myline.front();myline.pop();vis[u]=0;for(int i=head[u];i;i=q[i].link){int v=q[i].v,w=q[i].w;if(w){  // 只有残量>0的边才考虑if(~vis[v]) continue;  // 已访问过则跳过minroad[v]=min(minroad[u],w);  // 记录路径最小容量pre[v]=i;  // 记录到达v的边myline.push(v);vis[v]=u;  // 标记已访问            }}}if(vis[t]!=-1) return true;  // 找到增广路径return false;
}void update(){int now=t;while(now!=s){int id=pre[now];q[id].w -= minroad[t];  // 正向边减去流量q[id^1].w += minroad[t];  // 反向边增加流量now = q[id^1].v;  // 回溯到前一个节点}maxflow += minroad[t];  // 增加总流量
}

关键特点:

  1. 链式前向星存图cnt从1开始,方便用^1获取反向边
  2. 残量网络:正向边存剩余容量,反向边存已用容量
  3. BFS寻路:保证找到的是最短增广路径
  4. 反向边机制:允许"反悔",这是最大流算法的核心

时间复杂度:

  • O(VE²),其中V是节点数,E是边数
  • 每次BFS:O(E)
  • 最多进行O(VE)次BFS

算法正确性保证:

  1. 增广路定理:当且仅当残量网络中不存在s-t路径时,当前流是最大流
  2. 最短路径增长:每次找到最短增广路,保证算法终止
  3. 反向边:确保能找到全局最优解

与相关算法对比:

算法时间复杂度特点
EKO(VE²)实现简单,适合稀疏图
DinicO(V²E)分层图+多路增广,效率更高
ISAPO(V²E)改进的Dinic,常数更小

总结:EK算法通过不断在残量网络中寻找增广路径并更新流量,最终得到最大流。

#include<bits/stdc++.h>
#include<queue>
using namespace std;const int N=1000101;
int n,m,s,t,cnt=1;int head[N];
int vis[N];
//int vis[N];
int pre[N],minroad[N];
queue <int> myline;
struct edge{int v,w,link,u;
}q[N<<2];void put(int x,int y,int z){q[++cnt].v=y,q[cnt].u=x,q[cnt].w=z,q[cnt].link=head[x],head[x]=cnt;q[++cnt].v=x,q[cnt].u=y,q[cnt].w=0,q[cnt].link=head[y],head[y]=cnt;
}bool E_K_bfs(){memset(vis,-1,sizeof(vis));pre[s]=-1;vis[s]=1;myline.push(s);	minroad[s]=INT_MAX;while(!myline.empty()){int u=myline.front();myline.pop();vis[u]=0;for(int i=head[u];i;i=q[i].link){//	puts("check");int v=q[i].v,w=q[i].w;if(w){if(~vis[v]) continue;	minroad[v]=min(minroad[u],w);pre[v]=i;myline.push(v);vis[v]=u;			//	printf("v:%dminroad:%d",v,minroad[v]);}}}//puts("check");if(vis[t]!=-1){	return true;}return false;
}int maxflow=0;
void update()
{
//	puts("checkgood");int now=t;while(now!=s){int id=pre[now];q[id].w-=minroad[t];q[id^1].w+=minroad[t];now=q[id^1].v;}maxflow+=minroad[t];
}
int main(){//freopen("tt.txt","r",stdin);//freopen("tt.out","w",stdout);scanf("%d%d%d%d",&n,&m,&s,&t);for(int i=1;i<=m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);put(u,v,w);}while(E_K_bfs()) update();printf("%d",maxflow);
}

Dinic算法核心思想

Dinic算法是分层图+多路增广的网络流算法,比EK算法效率更高。

算法步骤:

  1. BFS构建分层图

    • 从源点s开始进行BFS
    • 记录每个节点到源点的最短距离(层数)
    • 只考虑残量>0的边
  2. DFS多路增广

    • 在分层图上进行DFS
    • 只向下一层的节点推进
    • 一次DFS可以找到多条增广路
  3. 重复直到无法构建分层图

核心代码:

bool bfs(){for(int i=1;i<=n;i++) deep[i]=MAX+5,vis[i]=0,cur[i]=head[i];deep[s]=0;while(!myline.empty()) myline.pop();myline.push(s);vis[s]=1;while(!myline.empty()){int u=myline.front();myline.pop();for(int i=head[u];i;i=q[i].link){int v=q[i].v;ll w=q[i].w;if(vis[v]||(!w)) continue;  // 已访问或残量为0if(deep[v]>MAX){  // 未访问过deep[v]=deep[u]+1;  // 记录层数myline.push(v);vis[v]=1;}}}if(deep[t]<MAX) return true;  // 能到达汇点return false; 
}

BFS作用:构建分层图,deep[i]表示节点i的层数

int dfs(ll limit,int st){if(!limit||st==t) return limit;  // 无流量或到达汇点ll flow=0,f;for(int i=cur[st];i;i=q[i].link){cur[st]=i;  // 当前弧优化int v=q[i].v;ll w=q[i].w;if(deep[v]==deep[st]+1&&(f=dfs(min(limit,w),v))){flow+=f;limit-=f;q[i].w-=f;q[i^1].w+=f;if(limit<0) return limit;}}return flow;
}

DFS特点

  • 多路增广:一次DFS可能找到多条路径
  • 当前弧优化:cur[st]避免重复检查无效边
  • 分层限制:deep[v]==deep[st]+1确保向下一层推进

Dinic算法的关键优化:

  1. 分层图:避免DFS绕远路
  2. 多路增广:一次DFS找到多条增广路
  3. 当前弧优化:避免重复检查已经"榨干"的边

时间复杂度:

  • O(V²E),比EK的O(VE²)更优
  • 对于单位容量图: O ( m i n ( V 2 / 3 , E 1 / 2 ) × E ) O(min(V^{2/3}, E^{1/2}) × E) O(min(V2/3,E1/2)×E)

与EK算法对比:

特性EK算法Dinic算法
寻路方式BFS单路增广BFS分层 + DFS多路增广
时间复杂度O(VE²)O(V²E)
实际效率较慢快很多
代码复杂度简单中等

代码中的关键点:

  1. 链式前向星cnt从1开始,方便反向边操作
  2. 当前弧优化cur[i]数组,避免重复检查
  3. 分层图deep[i]记录节点层数
  4. 多路增广:DFS中flow+=f累计多条路径

算法正确性保证:

  1. 分层图性质:确保找到的增广路是最短的
  2. 多路增广:充分利用每次BFS构建的分层图
  3. 当前弧优化:不影响正确性,只提升效率

总结:Dinic算法通过分层图限制DFS方向,配合多路增广和当前弧优化,大幅提升了网络流算法的效率

#include<bits/stdc++.h>
using namespace std;typedef long long ll;
const int N=1e4+5,M=1e5+5;
const ll MAX=123456789000;
int n,m,s,t;ll w;
queue<int > myline;
int head[N],cur[N],cnt=1;
ll deep[N];
struct edge{int link,v,u;ll w;
}q[M<<1];
bool vis[N];
void put(int u,int v,ll w){q[++cnt].v=v,q[cnt].u=u,q[cnt].w=w;q[cnt].link=head[u],head[u]=cnt;}
bool bfs(){for(int i=1;i<=n;i++) deep[i]=MAX+5,vis[i]=0,cur[i]=head[i];deep[s]=0;while(!myline.empty()) myline.pop();myline.push(s);vis[s]=1;while(!myline.empty()){int u=myline.front();myline.pop();for(int i=head[u];i;i=q[i].link){int v=q[i].v;ll w=q[i].w;if(vis[v]||(!w)) continue;if(deep[v]>MAX){deep[v]=deep[u]+1;myline.push(v);vis[v]=1;}}}if(deep[t]<MAX) return true;return false; 
}
int dfs(ll limit,int st){if(!limit||st==t) return limit;ll flow=0,f;for(int i=cur[st];i;i=q[i].link){cur[st]=i;int v=q[i].v;ll w=q[i].w;if(deep[v]==deep[st]+1&&(f=dfs(min(limit,w),v))){flow+=f;limit-=f;q[i].w-=f;q[i^1].w+=f;if(limit<0) return limit;}}return flow;
}
void Dinic(){ll ff=0;while(bfs()){
//		for(int i=1;i<=n;i++){
//			printf("deep[%d]=%lld ",i,deep[i]);
//		}
//		puts("");ff=ff+dfs(MAX,s);} printf("%lld",ff);
}
int main(){scanf("%d%d%d%d",&n,&m,&s,&t);for(int i=1;i<=m;i++){int u,v;ll w;scanf("%d%d%lld",&u,&v,&w);put(u,v,w),put(v,u,0);}Dinic();
}
http://www.dtcms.com/a/597720.html

相关文章:

  • 网络编程核心:套接字绑定(bind函数)与 IP 地址转换处理
  • 百度建站东莞著名网站建设
  • 如何选择邯郸网站制作做外贸网站维护费是多少
  • 【SCI复现】高比例可再生能源并网如何平衡灵活性与储能成本?虚拟电厂多时间尺度调度及衰减建模
  • CodeBuddy AI IDE:全栈AI开发平台实战
  • 购物网站开发教程 视频大流量网站 文章点击
  • 研究人员诱导ChatGPT对自身实施提示注入攻击
  • 数据结构与算法实验(黑龙江大学)
  • 孤客截图工具 Pro - 从开发到打包的完整指南
  • 山东德州最大的网站建设教学学校网站php源码|班级主页教师博客学生博客|学校网站织梦仿
  • 基于librespot的定制化Spotify客户端开发:开源替代方案的技术实践与优化
  • 主从同步配置的步骤
  • 个人使用网站wordpress用户设置
  • vps网站目录是灰色的生活中实用的产品设计
  • mysql主备配置(对比postgresql)
  • mysql tidb like查询有换行符内容问题解决
  • 【工具变量】上市公司是否获得ZF采购DID(2000-2025年)
  • 【AI学习-comfyUI学习-LCM lora八步生成 工作流-各个部分学习-第八节】
  • 转轮机加密(攻防世界)
  • 微信小程序实现长按复制选中文字的效果
  • SQL Server 驱动 和 TLS 版本不兼容 的问题
  • 【低空安全】低空无人机集群侦测与反制概述
  • 制作网站的原因是计算机网页制作工具
  • 机器学习聚类k均值簇数的调优方法
  • 批量格式化XML与JSON文件小工具
  • TensorFlow深度学习实战(41)——TensorFlow生态系统
  • 网站空格 教程宁波龙山建设有限公司网站
  • 4-ARM-PEG-COOH(2),多功能羧基PEG的结构特性与反应特点
  • 东昌府区网站建设公司铜川网站建设公司电话
  • 大模型如何处理不同格式的文档?