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

网络流 最大流

网络流 最大流算法

网络

图论中的网络是一种特殊的有向图,与有向图不同的是网络存在容量、源点和汇点

  • \(E\) 边集中的每一条边 \((u,v)\) 都有一个被称为容量的权值 \(c\)
  • \(V\) 点集中存在两个特殊点:源点 \(s\) 和汇点 \(t\)

在网络 \(G=(V,E)\) 中,流是一个从边集到整数集的一个函数,\(f(u,v)\) 表示边 \((u,v)\) 上的流量,\(c(u,v)-f(u,v)\) 表示这条边的剩余容量

在网络中,合法的可行的流应该满足性质:

  • 容量限制:\(0\le f(u,v)\le c(u,v)\)
  • 流量守恒:$\sum\limits_{(u,x)\in E} f(u,x)=\sum\limits_{(x,v)\in E} f(x,v),x\ne {s,t} $ ,形象化的说,一个普通点流入的容量等于流出的容量

最大流问题

我们希望在网络 \(G=(V,E)\) 中找到合适的流 \(f\) ,最大化这个网络的流量 \(\lvert f\rvert =\sum\limits_{x\in V}f(s,x)-\sum\limits_{x\in V}f(x,s)\)

增广路: 一条从源点到汇点的路径,路径上所有边的剩余容量都大于 \(0\)

残留网: 网络中所有结点和剩余容量大于 \(0\) 的所有边构成的子图

EK算法

在建图时给每个有向边都构建一条反向边,容量为 \(0\) ,目的是提供一条退流的路径,一旦前方的增广路无法连通可行流,那么就可以通过退流管道将增广路的部分流量退回

因为需要快速的定位反向边,所以采用链式前向星的方式存图

struct edge{int v; LL c; int ne;};
edge e[M];
int h[210], idx = 1;//从2开始给边进行编号,0是哨兵void add(int u, int v, LL c){e[++idx] = {v, c, h[u]};h[u] = idx;
}for (int i = 1; i <= m; i++){int u, v;LL c;cin >> u >> v >> c;add(u, v, c);add(v, u, 0);
}

通过 BFS 找到一条增广路

类似贪心的扩展,每次只走到一个没有被访问过的节点

int pre[210];//记录节点的前驱边
LL mf[210];//s到该点的流量上限bool bfs(void){memset(mf, 0, sizeof mf);queue<int> q;q.push(s);mf[s] = 1e9;while (q.size()){int u = q.front();q.pop();for (int i = h[u]; i; i = e[i].ne){//枚举所有出边int v = e[i].v;if (mf[v] == 0 && e[i].c){//只有这个邻点没有被访问过且有容量mf[v] = min(mf[u], e[i].c);pre[v] = i;q.push(v);if (v == t) return 1;//能走到汇点}}}return 0;//不能走到汇点,说明无可行流
}

每轮 BFS 都找到一条可行流,累加这些流的流量,然后构建残留网

LL EK(void){LL flow = 0;while (bfs()){//存在可行流时int v=t;//从汇点出发while (v != s){//回溯到源点int i = pre[v];e[i].c -= mf[t];e[i^1].c += mf[t];//更新退流管道v = e[i^1].v;//走反向边}flow += mf[t];}return flow;//返回最大流
}

总的时间复杂度上界为 \(O(nm^2)\) 的级别,\(n,m\) 分别为点数和边数,实际上会比这快得多

Dinic算法

区别于 EK 算法每一轮只累加一条增广路的流量,我们可以先将点 BFS 分层然后通过 DFS 寻找多条增广路

LL dfs(int u, LL mf){if (u == t) return mf;//如果到终点,返回流量LL res = 0;for (int i = cur[u]; i; i = e[i].ne){cur[u] = i;//当前弧优化int v = e[i].v;if (dep[v] == dep[u] + 1 && e[i].w){//只有当下一个节点是下一层时才搜索LL f = dfs(v, min(mf, e[i].w));//流量限制e[i].w -= f;e[i ^ 1].w += f;//退流res += f;//累加当前流量mf -= f;if (mf == 0) break;//如果当前节点以及没有流量就立即返回}}if (res == 0) dep[u] = 0;//残枝优化return res;
}

其中的当前弧 cur[u] 表示节点 \(u\) 在链式前向星中已经考虑过了哪些边,再次进入循环时就可以跳过这些边

残枝优化的意义时,如果当前节点的 res\(0\) ,这个节点就不会连通到汇点,所以在当前的残留网中就不需要考虑了

LL dinic(){LL flow = 0;while (bfs()){memcpy(cur, h, sizeof h);//重置当前弧flow += dfs(s, 1e9);//累加可行流}return flow;
}

时间复杂度为 \(O(n^2m)\) 级别,在稠密图中的运行效率很优

http://www.sczhlp.com/news/62753/

相关文章:

  • 集训总结(一)
  • 网址与网站的区别网站推广软文
  • 密云成都网站建设wordpress主动推送所有网址插件
  • 电子商务网站建设问题旅游网站国内外研究现状
  • 网站上常用字体网站建设的工作职责
  • 接订单去哪个网站计算网站制作教程
  • 亚马逊电子商务网站的建设网站建设素材使用应该注意什么
  • 互助盘网站开发沈阳市城市建设网站
  • seo优化网站的注意事项乐清网站网站建设
  • 天河网站 建设信科网络谷歌竞价广告
  • 美剧网站怎么做网站后台作用
  • 专业建站方案泗阳县住房和城乡建设局网站
  • 网站活动页面建筑工人找活正规平台
  • 沙漠风网站建设公司用vs2012做网站案例
  • js网站特效二手房公司网站源码
  • 银行系统网站模板网站备案是备案域名还是空间
  • 企业网站制作公司有哪些手机海报制作app
  • 北京网站制作招聘网天津市网站制作建设推广公司
  • 做快递网站制作富阳网站公司
  • 内贸网站有多少2017年网站建设高职考f卷
  • qoj10536 Card Flipping
  • 杂谈25.9.2
  • 小说网站开发实录顺的网站建设策划
  • 网站及微信建设是否涉及知识产权网站怎么样做优化
  • 郑州建站以来深圳+服装+网站建设
  • 用阿里云自己建设网站wordpress有些主题和
  • 如何做网站海报西安优化官网公司
  • 建设银行嘉兴分行网站首页网站备案号 脱离服务商
  • 漯河做网站的店西安高端品牌网站建设
  • 广西住房城乡建设厅网站中国五大门户网站