网络流建模汇总by Edelweiss
网络流比较考思维,一般来说只要建模正确,就可以直接连边套模板了。
(加*的都是感觉比较经典/巧妙的题)
文章目录
- 最大流
-
- *POJ1149PIGS
- POJ1637Sightseeing tour
- POJ2391Ombrophobic Bovines
- POJ2699The Maximum Number of Strong Kings
- POJ3281Dining
- *JOJ2453Candy
- ZOJ2760How Many Shortest Path
- WOJ1124Football Coach
- SGU326Perspective
- *SGU438The Glorious Karlutka River =)
- *SPOJ287Smart Network Administrator
- SPOJ962Intergalactic Map
- 最小割
- 有上下界
- 费用流
- 总结
最大流
*POJ1149PIGS
把猪圈每天都拆出一个点。
点数是 n m nm nm级别的,考虑优化最原始的连边:
哪些点是等价的呢?又有哪些边是没用的呢?
- 点:流量的来源/去向完全相同,或者连边 ( u , v , + ∞ ) (u, v,+\infty) (u,v,+∞)且 v v v仅有 u u u这一个流量来源。
- 边:合并后的两点之间的多条边(可以由一条总流量大小的边替代)
经过复杂的整理之后(过程略),得到简化模型:
- 每个顾客是一个结点,均向汇点连一条容量为购买上限的边。
- 源点向所有猪圈的第一个顾客容量为相应数量的边。若多个猪圈指向同一个顾客,只用连一条容量为总数量的边。
- 对于每个猪圈,假设有 n n n个顾客光顾过,则第 i ( 1 ≤ i < n ) i(1\leq i<n) i(1≤i<n)个顾客向第 i + 1 i+1 i+1个顾客连一条容量为 + ∞ +\infty +∞的边。
(顾客之间的连边还可以简化/缩点,但过于麻烦且没有必要)
点数是 n n n级别的。
(形式上很优美)
POJ1637Sightseeing tour
当且仅当图中所有点入度=出度时存在欧拉回路。
首先随便给无向边定向,求此时每个点的出度-入度的值 d i d_i di。若 d i d_i di为奇数,则无解(欧拉回路中不能存在总度数为奇数的点)。所以所有 d i d_i di都为偶数,设 x i = d i 2 x_i=\dfrac {d_i}{2} xi=2di,对于点 i i i,只要将连向它的 x i x_i xi条同向的边改成另一个方向即可。
问题转成了改变一些边的方向,使得每个点入度=出度,考虑构图:
- 若 d i > 0 d_i>0 di>0,连边 ( S , i , d i ) (S,i,d_i) (S,i,di);若 d i < 0 d_i<0 di<0,连边 ( i , T , − d i ) (i,T,-d_i) (i,T,−di)
- 仅保留图中任意定向后的无向边(删去原来的有向边),且每条边容量为1。
考虑流过这条边相当改变了这条边的方向,最后检查是否满流即可。
POJ2391Ombrophobic Bovines
构图:
- 拆点(每个点拆为入度 i i i和出度 i ′ i' i′)。源点向 i i i连容量为 A i A_i Ai的边, i ′ i' i′向汇点连容量为 B i B_i Bi的边。
- 先求出两两之间最短距离,二分时间 m i d mid mid,每次只连 d i s ( i , j ) ≤ m i d dis(i,j)\leq mid dis(i,j)≤mid的边( i , j ′ , + ∞ i, j',+\infty i,j′,+∞),判断是否满流。
注意不拆点是错的:
( i , j ) , ( j , k ) (i,j),(j,k) (i,j),(j,k)连边而 d i s ( i , k ) > m i d dis(i,k)>mid dis(i,k)>mid但此时 i i i可以流到 k k k,所以连接 ( i , j ) (i,j) (i,j)时必须要强制 j j j就是终点,所以要拆点把入度出度分开。
POJ2699The Maximum Number of Strong Kings
原文有点问题:
strong king并不一定是最大的 k k k个,但最大的 k k k个是strong king一定是合法的(证明略)。
n ≤ 10 n\leq 10 n≤10,考虑枚举strong king的个数 k k k,将选手按得分降序排序后选择前 k k k个:
- 每个选手看做一个点 i i i,连边 ( i , T , s c o r e i ) (i,T,score_i) (i,T,scorei),若 i i i为strong king,则再拆出一个点 i ′ i' i′,连边 ( i ′ , i , k t h i ) (i',i,kth_i) (i′,i,kthi)( k t h i kth_i kthi表示分数比 i i i高的选手数,拆分出来强制选满)。
- 每个比赛看做一个点 i i i,源点向 i i i连容量为1的边,设比赛双方为 ( u , v ) (