网络流

 


网络流

基础知识

定义

一张 网络:由一个图和一个函数 C:ER 组成。C(e) 表示一条边 e容量

其中有两个关键的点,称为 源点(S)汇点(T)

下面用 C(x,y) 表示 x,y 这条边的 C 函数值。对于其它定义域为边集的函数都写成这样。

一个合法的 :考虑这样的一个函数 f:ER,满足:

  • 流量平衡: uS,T,vuf(v,u)=uvf(u,v)
  • 斜对称性:uv,f(u,v)=f(v,u)
  • 流量限制:uv,f(u,v)C(u,v)

可以推得:

  • Suf(S,u)=uTf(u,T)

把这个值称为这个流的 流量

有一个形象的理解是,S 为自来水厂,T 是你家,每条边相当于是一个水管,带一个容量限制。然后中间有若干的中转站(并不能提供水)。流量就是流到你家里水的数量。

一类问题是,最大化流量。 称为 最大流问题

一类问题是,有一个费用函数 w:ER,表示每条边每个单位的流量所需要付出的费用。在最大化流量的前提下,最小化代价。称为 最小费用最大流 问题。

此外,还有一类问题叫做 “最小割”。严格定义如下:

  • 将点集 V 划分成 A,B 两个集合(即,AB=,AB=V),使得 SA,TB
  • 定义割的大小为:uA,vBc(u,v)。最小化这个东西。

换句话说,就是:切掉一些边使得 S,T 不连通,最小化切掉的边的边权和。

【定理】最大流=最小割

证明:首先显然每个流都每个割。然后做完最大流的时候,在残量网络上,把 S 能到的那些点设为 A 集,剩下的设为 B 集,A,B 就构成一个最小割,且这个割的大小就等于最大流。

最大流 - Dinic算法

首先我们发现,“流”这个东西其实就是很多条从 ST 的路径,每条路径流了一个流量,叠加起来,然后给反向边放一个负权就行了。总流量就是每条路径流的流量和。

注意到,“流”和“ST 路径”都满足除了 S,T 外的点流量守恒。

那假设咱现在有一个流。它是最大流吗?怎么把它变更大?

有一个显然的想法是我再找一条路径,叠加上去。如果流完之后还能满足流量限制,那我们就可以把流量加上这条路径流的量。

这玩意可以转化为:每次流完之后,我们把一条边的容量设为它还剩下的流量 C(u,v)=C(u,v)f(u,v)。这样得到的网络称为 残量网络。同时,这条路径被称为 增广路

反之,如果我们找不到增广路,那就说明当前是最大流了。

那如果我们有一次流错了,导致我找不到增广路,但还不是最大流?有没有这种情况?

注意到我们每条边有一个负权的反边。那如果 uv 流了一个流量 f,那么残量网络上 C(v,u)=0(f)=f。(注意到 C 的限制是针对 uv 的,vu 容量限制为 0,如果没有另外加边的话)。如果我们有一个增广路流了这一条边,就相当于把这次 uv 的流 反悔 了。

这个机制确实保证了正确性,但是复杂度与容量有关。如果容量 1e9 直接挂了。

Dinic算法就解决了这样一个问题:我每次先BFS把图分层,每次只从上一层流到下一层。

然后它就跑的飞快了。

板子

Dinic: 代码

一些易错点:

  • BFS中, 不要忘记返回值,以及dep和Q的清空;对于当前弧优化,记得把当前弧搞出来
  • DFS也不要忘记返回值
  • 网络流别忘记clear
  • 网络流中不要忘记定义变量 S,T
  • DFS(S,INF)
  • F(i,1,tot) dis[i]=INF;
  • 最大费用最大流,你应该判 dis[T]<=-INF 的时候 break,而不是 dis[T]<0

通常,网络流题目并不难在写出来网络流(除非出题人卡常,要写一些比dinic快的网络流),而是把模型建出来。

最大权闭合子图模型

一个有向图中,每个点有一个权值,可能正可能负。选一个点,就要选这个点所有后继。请选择若干个点,满足条件,且权值和最大。

这就是 “最大权闭合子图” 模型。

可以采用最小割建图来解决这个问题。有两种常见的思想:割一条边代表选,以及,割一条边代表不选。

分析一波。对于这个问题,我们考虑:假设没有任何限制,那肯定就把所有正的全都选上。

但是我们选了某些正的点,可能相应的就要选一些负的点。

对 “选...就要选...” 进行一个联想:在一张图上,要把 S,T 割开,如果我要保留一些边,就必须割掉另外一些边。也就是 “保留...就要割...” 的模型。

对于每个正权的点,要选它,就要选另外一些点。把权值放在边上,就变成 “选...就要选...” 模型。

根据上面的联想,我们令正权点连的边, “保留” 为 “选”。那它后继应该有一些能到 T 的边,使得它能构成 “保留...就要割...” 模型。

而且后面这些边,应该反过来,是以 “割” 为 “选”。

注意到,“保留”为“选”,相当于“割”为不选。那我们先全选,减掉割,就行了。

后面以“割”为“选”,我们考虑能不能保持同步,也是用 “全选,减掉割” 的办法处理。

啪的动一下脑子:对于负权点 a,我们连一条权值为 a 的边。如果割掉,就表示选了这个负权点。好对啊!!!

那我们现在已经有了 “全选,减掉割” 这个idea了,并且,我们要把点权放在边上。

那我们具体怎么连边呢?考虑 “保留...就要割...” 模型,总体上大概是前者离 S 近,后者离 T 近。

那我们干脆把前者连到 S,后者连到 T。也就是说,把正权接在 S 上,负权接在 T 上。对于 “选...就要选...”,直接连边就行。

仔细一想,这样好像就对了!

总结一下:

  • 对于正权点 u,权值为 ai,我们连边 Saiu
  • 对于负权点 u,权值为 ai,我们连边 uaiT
  • 对于原图上的 uv,连边 uv
  • 正权和 - 最小割,为答案

这是一个常见模型。有很多延伸应用。

板子:洛谷 3410, [网络流24题]太空飞行计划问题

最大权导出子图 / 最大密度子图(poj 3155)

最大权导出子图,很好理解。就是点和边都带权,找一个导出子图,使得权值和最大。

考虑导出子图这个事情:如果选了一个边,就要选它两边的点。

把边建出来点,那它就变成了最大权闭合子图。

定义一个导出子图的密度为:边数/点数。找到最大密度的子图。

考虑二分。假设密度能 >ρ,设边数、点数为 E,V,则 EV>ρ

也就是说 EρV>0。设边权为 1,点权为 ρ,找到最大权导出子图,看看是否 >0

(注意要严格大于,因为如果是 0,你不选也 0,没法限制)

然后卡卡精度就行了。

经典in-out拆点

对于一个点 u,拆成 u1,u2u1u2 连一条边,边权为 u 的点权。

这样就可以把点转换成边,用边来做点。

SCOI2007 蜥蜴

我们发现这个东西很像一个最大流。但是限制不在边上,而是点:每个柱子有被经过次数的限制 h(i,j)

对于 (i,j) 位置的点,我们把它in-out拆点,然后中间那条边权设为 h(i,j),即可解决这个限制。

对于原图上 uv 的边,连边 u2v1 即可。

洛谷1345

这题是一个“最小点割”:每个点带点权,割若干个点使得 c1,c2 不连通。最小化割掉点的权值。

c1,c2S,T。我们把点in-out拆点后,把中间那个边权设为该点的点权。u2v1 的边权设为inf。

求这个图的最小割,显然只会割在点中间那个边上。我们发现它就和原图割点的方案一一对应。求这个最小割就行了。

三元匹配

有三类点,A,B,C。边只会是 AB,BC 类型的。

对于一个 a,b,c,满足:

  • aA,bB,cC
  • abbc 之间,都有边

(a,b,c) 是一组三元匹配。一个点只能被匹配一次。请你选出最多的三元匹配。

(相当于把二分图匹配扩展一下)

根据二分图匹配的套路,对于 aA,cC,我们连边 Sa,bT,容量为 1,就可以限制 a,c 只被选一次。

但是 b 可能被选很多次,那咋办?我们不能靠 S,T 了,靠自己!我们自己裂开来,in-out拆点,中间连一条边,容量为 1。这样就可以限制它只被选一次了。

然后跑最大流即可。

这个技巧也可以解决更多元的匹配。

例题如:洛谷1402,1231 (其实算是双倍经验了)

环覆盖

对于一个有向图,“环覆盖”可以看成是入度与出度的匹配。

然后就直接连边做就行了,注意一个点可以匹配很多次,所以连到 S/T 的边容量为它的入/出度。

例题如 CF510E,也没见到别的。

二元选择

每个东西只有两种选择,选 A 或者选 B。两种选择有各自的收益。

还有若干关系:若...选择...,则有额外收益。

不需要像刚才那样拆成两个点,直接把每个点连 S 表示选 A,连 T 表示选 B 即可。

关系另外处理

小M的作物 / 文理分科 / happiness

这三个题本质上是一个题,都可以在洛谷上找到(

概括一个共同的题意:

  • 每个点二元选择,选 A 获得价值 Ai,选 B 获得价值 Bi
  • 有若干个关系。每个关系分 A,B 类型,用一个集合 Si 和权值 vi 描述。若 S 集合中所有人同时选了 A/B,则额外获得 vi 的收益
  • 最大化总收益

按照二元选择的模型建图。然后我们用 “割” 代表 “不选”。

对于每个关系,观察它的形式(以 A 型举例):若干个点同时割掉到 T 的边,这个关系才能形成。

令关系也是“保留”代表“选”,这个就是上面提到的模型:“保留...就要割...”

那把关系 i 搞出来一个点 piSvipipix(xS)

这样,只有当 S 中所有元素都选 A (割掉 B)的时候,才能选这个关系,符合题目的要求。

然后用全部权值和减去最小割,就是最大的收益了。

SHOI2007善意的投票 / JLOI2010冠军调查

先搞一个二元选择模型建图。接下来,与上题不同,我们要解决“不同”。

这个东西更加简单。我们用“割”表示“选”,那只要在 uv,vu 之间都连一个 就行了。

这样 u,v 必须选相同,才能避免这个额外的代价。否则,就会有一条通路过去。

然后求最小割就行了。

多元选择拆点

n 个东西,都有很多个选项。我们可以把每一个选项拆点,解决选项之间的限制问题。

它可以结合距离限制模型,解决更多问题。

SCOI2007 修车

对于一个师傅,它可能会修 1,2,3...n 辆车。我们把这 n 种选择全都拆成点。

注意到它依次修 k 辆车,时间为 a1,a2...ak,总时间为 ak+2ak1+3ak2...+ka1。越靠后,系数越小。换句话说,系数是 “倒数第几个”。

那我们这么拆:对于这个师傅 x,拆点 x1,x2..xn 表示:修倒数第 1,倒数第 2....倒数第 n 辆车。

那给它一个 1,2,3...n 的费用就行了。容量为 1,表示修一辆车。

S 先连到一个 S,容量为 n,表示必须修 n 辆车。然后 S 连到每个师傅。每个车再连到 T,容量为 1,表示每辆车恰好被修一次。

以下是某个同学代笔写的,与文章内容无关,但文笔太好了,让我们来欣赏一下。

lzj会站在这些车前面,他认为这些车修的不好,于是一个个教育这些师傅,朝问道,夕死可矣,在修车的时候没有注入灵魂,看不出人的傲骨,车乃大丈夫行天下之利器,辙及天南海北,反映的是一个人的精神和风骨,君子者,为天地立心,为生民立命,为往圣继绝学,为万世开太平,一个合格的修车夫,应饱含理想主义的信仰,做一名斯多葛派的信奉者,不灭人生而有之的飒踏和洒脱,在尘世面前,保持初心,而不是庸于俗世泯然芸生,心之所行,万物随之奔流,修车乃格物之道,正如王阳明的心学理念,需人神之悟道,皆物我合一。我们看穿车之本质,其属性为两个标量,在一维不可逆的时间体系逻辑中,我们需以lzj的自我基础元的意识世界为第一视角,从计算的本质——映射开始,领悟绝世大儒对此题的理解和悟道,总而言之,AprilGrimoire txdy !!!!!!1

距离限制模型

每个东西有若干个选项,第 i 个东西的选项有编号 j[1,m],并且有权值 vi,j。首先我们用上一个模型,把这些选项拆点。

拆完点之后,东西之间有选项的限制。设 i 这个人选的选项是 ci。有若干个限制,每个形如:cicj/k。我们需要满足每个限制,然后使权值和最小或最大。

这个就是距离限制模型。

它有一些延伸,比如说我们要做 |cicj|k,就可以转化成 cicjkcjcik,再套用这个模型。

那它怎么做呢?

其实我们并不是把选项拆“点”,而是拆“边”。对于每个选项,我们拆出 m+1 个点,连成一条链。中间 m 条边的权值是每个选项的权值。S 到最开始的点,最后的点到 T ,有两条 的边。然后我们认为 “割” 为 “选”。

形式化地,对于第 i 个东西,我们设它拆成的点是 Ai,1...Ai,m+1

如下建图:

i[1,n],{SAi,1TAi,m+1j[1,m], Ai,jvi,jAi,j+1

称这玩意为东西 i 的 “选项链”。 我们把每个东西的 “选项链” 都建出来。

这是一个经典的建图,它有什么性质?

我们在链之间横向插边!

比如我们在 Au,iAv,j 之间连一条 边。那么,如果 v 选在 j 之前,u 就要选在 i 之前。否则就会有 SAu,iAv,jT 这样一条通路。

对于一个 d,考虑:i,连边 Au,iAv,i+d 。如果 v 选在了 i,则 u 必须选在 id 之前。这就实现了 cvcud

然后求最小割就是最小的权值和。

那么问题来了,如何求最大的权值和?

首先我们搞一个够大的数 M,然后把每个 vi,j 变成 Mvi,j。然后用 M×n 减去最小割即可。

感性理解:假设默认可以得到 M 的收益,考虑每个选项 损失 的收益。让损失最小,就等价于权值和最大了。

直接应用:HNOI2013 切糕,codechef RIN

行列建点

适用于网格图的建图技巧。

把每行、每列都看成点,把位置 (x,y) 看成行与列的关系,建边。

一般题目难都难在想到这样建,以及处理关系呢。

大概就是这样的套路吧(笑)。

bzoj4883

把每个格子看做行与列连了一条边,然后要定向。指向的那个点就是这个格子控制的点。

那我们一共要选 n+m 个边和点。那很显然就是一个基环树森林。

用并查集就可以类似kruskal贪心的做了。

虽然不是网络流题,但可以根据这个题,熟悉一下行列建点是怎么建的。

洛谷4311

逆向思维。假设一开始每个位置都有士兵,最少删掉多少个士兵?

删掉一个士兵,相当于把它对应的行和列都减少了 1 的贡献,答案也可可以变小 1。这就像我们把这里原来的一条流给取消了,三条边的流量都 1 且答案 1

我们把 S 连到行点,列点连到 T。对于中间的一个格子,连接它对应的行列点,容量为 1

对于每行每列,我们把它连到 S,T 的边的容量,设置为它最多能删掉多少个士兵使得它能满足条件。

显然这张图的最大流就是最少删除的士兵数,拿总数减掉就行。

HEOI/TJOI2016 游戏

假设没有石头,答案就是 min(n,m)

我们可以把它看成是行点与列点的匹配。每个可以放炸弹的格子相当于连接了一个行点和一个列点,答案就是最大匹配。

这样就可以做仅有软石头的情况了。考虑硬石头咋做。

现在放了一个硬石头,考虑它的那一行(列同理),如果我们在左边和右边放了一个炸弹,我们发现没事。因为这个硬石头把它们隔开了。

那其实我们以为这是 “一行”,但其实并不是 “一行”,它相当于是裂开了,变成两 “小行”。在两个“小行”内部不能同时有炸弹,但是在“小行”之间没有限制。

因此我们可以灵活运用这个拆点,把行再拆开。给这些拆开来的行赋予一个新的编号。

同理,我们给拆开来的列也分配新的编号。

然后就对这些 “新行”,“新列” 做最大匹配就行了。

SCOI2015 小凸玩矩阵

每行每列选一个 行列匹配,直接行列建点。

那第 k 大怎么做?

先二分,设第 k 大能 mid,那么 mid 的设为 1<mid 的设为 0。我们得选出 k 个以下的 1

1 的个数其实就是行列的最大匹配数。然后就每次跑一遍二分图匹配,然后check一下就行了。

最小路径覆盖模型

不太会,我去学一学

杂题

网络流24题 最长不下降子序列问题

第一问显然是dp。第2,3问似乎不能dp了。

第2问很像一个最大流。我们给每个点加一个只能选一次的限制,用容量来限制就行。限制在点上,看来需要做一个 in-out 拆点。

我们要保证每一条流,都对应着一个LIS。怎么做呢?

考虑一个LIS,它上面的dp值应该是连续+1的,并且位置也是递增的。

那对于 i<j,dpi+1=dpj,我们连边 i2j1,容量为 1。然后最大流就是答案了。

对于第三问,把点 1,n 内部的限制与它们到 S,T 的容量限制变为 ,就行了。

CQOI2009 跳舞

这题相当于明示了用网络流吧。感觉好像对着网络流的意义建边就行了,建完发现不太行。

首先一个问题是,不好处理“不喜欢”的限制。那好办,把不喜欢拆出来一个点。然后它来一个容量限制 k 就行了。

由于喜欢和不喜欢都是相互的 (单恋人落泪),“喜欢”相互连,“不喜欢”相互连就行了,不存在喜欢连到不喜欢的情况。

还有一个问题是,我们求出来它最多配成多少对,但是并不能直接得知能不重复的完美匹配多少次。

那咋办呢?考虑二分!

首先二分性显然是有的。然后对于一个 mid,匹配的对数应该至少是 mid×n,然后才能完美匹配 mid 次。

我们可以在 S,T 那边,给每个人加一个 mid 的容量限制,表示这个人最多参加 mid 轮跳舞。

此时流量最大是 mid×n,判断它是否等于 mid×n 就行了。

容易证明如果流量为 mid×n,一定有解。

然后就二分做一下就没了。

ZJOI2009狼和羊的故事

很明显,有两种东西,根据上面做这么多题的经验,啪的一下想到:S 连到羊,狼连到 T

接下来我们要设置最少的篱笆使得狼和羊不连通。这显然就是一个最小割问题。而且狼和羊不连通,等价于 ST 不连通。那转化都不用转化,只要每个点向周围连一条边,容量为 1,就行了。

POI2005 KOS-Dicing

对于一个比赛 a,b,相当于要从二者中选一个,对其胜利次数 +1。然后我们要最小化这个最大值。

最大值最小,啪的一下,二分。 (注意到确实有可二分性)

然后现在变成了:对于一个 k ,是否可以让每个人的胜利次数都 k

考虑网络流,每流到这个人一次就看成是次数 +1。对于限制,我们把这个人连到 T,容量为 k,就限制了它只能赢最多 k 次。

对于一个 “二选一”,在生活中也很常见:用一个“分流”模型,实现这个事情。

具体的说就是一个三叉结构。首先我们把每个游戏建成一个点 gi,设这场游戏里的两个人是 ai,bi,那么连边 Sgi, giai, gibi,容量都是 1。由于 Sgi 的容量是 1,那么这个流该去向何方,只能在 a,b 两者中选了,就实现了二选一这个事情。

然后看看每个 Sgi 是否都有流量。它必须全都有流量,k 才合法。如果有某个 gi 没流过来,那说明我们必须要把这一场比赛扔掉才能满足条件,而不能带上它一块满足条件,说明这个 k 太小了。

并不需要写个循环,只需要判断最大流 =m 即可。

网络流24题 方格取数问题

二分图带权最大独立集。(注意到网格图是二分图)

首先,看到“二分图”的这个“二”,我们就想到 S,T。把其中一部分连到 S,另一部分连到 T。边权就是这个点的点权。

然后还有一个问题,有些点不能同时选,就是原来二分图上有边的两个点。如何限制不能同时选呢?

设“割”为“不选”。那两个东西同时选,就会保留两条边。保留两条边,如果给它中间加一条inf边,就不合法了。

那容易得到,给原来有边的两个点,加一个inf边,就能限制这两个点里面一定要割一个。

拿权值和减去最小割就行了。

poj1149 pigs

“任意调换顺序”,即,保持和不变的情况下,可以随便指定哪里多少猪。

观察网络流的过程。对于一个点,如果有一堆流过来了,那都可以“储存”在这个点上(参考上面自来水厂和中转站的理解),然后保持和不变的情况下,任意的流出去。

那其实我们可以把猪当成流。然后猪给了一个人,我们就把这里所有的猪,都暂存在人这里。人到汇点有一个边,带容量限制,表示这个人要的猪数量。那剩下的猪就会留在人那里,在保持和不变的情况下,任意分配。

那如果接下来还有人来买猪,就从上一个人连到这一个人就行了。这样就实现了猪在保持和不变的情况下任意分配这件事情。

然后跑最大流就是最多的卖猪的数量。

网络流24题/CTSC1999 星际转移问题

很显然,把人看成流。然后人就在星球之间流动,地球看做源点,月亮看做汇点。

但是我如果直接建图,流是流过去了,用了多少时间呢?不知道。而且不同时刻,有哪些边也不一样。

观察一下,当前有哪些太空船,从哪到哪,随时间规律的变化。

和时间有关,一拍脑袋,想到用分层图建图。然后这样也就解决了不同时刻边不一样的难题。

盗用洛谷题解里的一张图,

这张图非常清楚的讲明白了如何建图。但有一个不太对,就是每一层的月亮都要向 T 连一条边。

然后看看最大流是否等于地球上的人数即可。可以用二分,或者在残量网络上不断的加一层,都可以实现。

神仙题: [Neerc2016]Delight for a Cat

令睡觉为 0,吃饭为 1。设 i 位置的状态为 xi{0,1}

那么对于每个区间,设和为 S,我们可以得到:

t2Skt1。设 L=t2,R=kt1,那么 S[L,R]

拆开来写,

{x1+x2...+xkLx1+x2...+xkRx2+x3...+xk+1Lx2+x3...+xk+1R...xnk+1+xnk+2...+xnLxnk+1+xnk+2...+xnR

2(nk+1) 个。

然后我们把不等式变成等式。怎么变呢?ab,看成是 a=b+x(x0)

对于每个 SL,设 S=L+yi。对于每个 SR,设 S=Rzi

然后得到 2(nk+1) 个等式:

{x1+x2...+xk=L+y1x1+x2...+xk=Rz1x2+x3...+xk+1=L+y2x2+x3...+xk+1=Rz2...xnk+1+xnk+2...+xn=L+ynk+1xnk+1+xnk+2...+xn=Rznk+1

一个转化:在最下面添加一个等式 0=0 (废条件)。然后,对这些等式,做一个,差分!

得到:

{x1+x2...+xk=L+y1y1+z1=RLxk+1x1=(LR)+y2+z1y2+z2=RL...xnxnk=(LR)+ynk+1+znkynk+1+znk+1=RLxnk+1+xnk+2...+xn=Rznk+1

这样是 2(nk+1)+1 个等式。

可以手玩一下,发现:每个 xi,yi,zi 都恰好出现两次。如果我们恰当的移项,恰好一次在左,一次在右出现!

如下是一种看起来挺好看的变形

{y1+z1=RLy2+z2=RL...ynk+1+znk+1=RL

{x1+x2...+xk=L+y1xk+1+(RL)=x1+y2+z1xk+2+(RL)=x2+y3+z2...xn+(RL)=xnk+ynk+1+znkR=xnk+1+xnk+2...+xn+znk+1

接下来是更加妙妙的操作:把等式看成点,两边相等看做流量平衡!

然后,我们把左边看成流入,右边看成流出,对于每个变量,直接把流出点连向流入点就行了!!!

注意到我们还需要让选出来的 x 权值和最大。那考虑费用流。

我们默认全都睡觉,先加上睡觉的权值,然后每个 x 的权值是 eisi

y,z 没有限制,容量为 ,费用为 0

x 的容量为 1 (只能取 0/1),费用为 eisi

对于常数项 L,R,容量为常数的值,费用为 0

然后跑最大费用最大流,取费用即为答案。

神仙题: WC2007 剪刀石头布

如何计算三元环的数量?

对于一般图, 当然不好做,但这是一个竞赛图。我们考虑先任选三个点, 它们之间显然会有三条边。

但这三条边必须“接起来”,才能构成三元环,否则就不行。

什么情况是“接不起来”的?一想,发现,有一个点出度为2,就gg了。再一想发现,这玩意是充分必要的。也就是说,如果没有点出度为2, 就一定能构成三元环。

那就好办了,答案就是 (n3)i=1n(di2),其中 di 表示 i 点的出度。

现在我们有一些边 (u,v),要给它定向。这个事情等价于在 u,v 中选择一个,把它的出度 +1

观察到, di 变成 di+1 后,它对答案的新增的贡献是 di

这是一个常识,因为:

(n+12)(n2)=n(n+1)n(n1)2=n

而我们要让答案尽可能的大,也就是减的尽量少。考虑最小费用最大流。

这里有一个不好处理的是, 贡献会随着不断的选择, 动态的变化。我们不能把所有选择放一块考虑了,联想到上面说的“多元选择拆点”, 以及修车师傅那个题, 考虑把每次选择拆开。

每个点 u,可能被加 0 次,1 次,或者更多次。初始的贡献是 (du2)。加一次,新增贡献 du。加两次,新增贡献 (du+1),以此类推。

那我们把每个点都往 T 连一堆边,容量都为 1,费用依次是 du,(du+1),(du+2)...,表示它被加一次,加两次,加三次...所对应的情况。注意这里的费用是指“损失的”三元环数量,所以是正的。

对于每条边 u,v,把它也建出一个点,设为 p。它要在 u,v 两个点中二选一,给它 +1 ... 等下,咱好像见过!

什么?你没见过?那你没仔细看上文

同样用那个 “分流模型”,S1pp1u,v,费用都为 0

这个图一定满流吗?想想发现,我们给每个点连到 T 的边都足够多,所以最后每条“边”(指它建出来的点 p) 一定都能有恰好 1 的流量。

最后,拿 (n3) 减去最大流前提下的最小费用,就是答案了。

怎么只有这么点题啊

在写了在写了

todo:

  • 网络流24题
  • 最小路径覆盖 相关问题
posted @   Flandre-Zhu  阅读(68)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示