一,基础知识
割
- S S S 是一个点集,保证 S S S 内一定有源点 s s s
- T T T 是一个点集,保证 T T T 内一定有源点 t t t
- [ S , T ] [S,T] [S,T] 定义为一个割
- c ( S , T ) c(S,T) c(S,T) : 一个割的容量(不考虑反向边,只考虑从S出发的)
- f ( S , T ) f(S,T) f(S,T) : 一个割的流量(考虑到从T回来的退流部分)
- 最小割:容量最小的割
割的性质
引理:
(以下大写字母 X,Y 代表点集)
1,
f
(
X
,
Y
)
=
−
f
(
Y
,
X
)
f(X,Y)= -f(Y,X)
f(X,Y)=−f(Y,X)
2,
f
(
X
,
X
)
=
0
f(X,X)=0
f(X,X)=0
3,
f
(
Z
,
X
∪
Y
)
=
f
(
Z
,
X
)
+
f
(
Z
,
Y
)
f(Z,X \cup Y)= f(Z,X)+f(Z,Y)
f(Z,X∪Y)=f(Z,X)+f(Z,Y) 条件:
X
∪
Y
=
∅
X \cup Y = \varnothing
X∪Y=∅
4,
f
(
X
∪
Y
,
Z
)
=
f
(
X
,
Z
)
+
f
(
Y
,
Z
)
f(X \cup Y,Z)= f(X,Z)+f(Y,Z)
f(X∪Y,Z)=f(X,Z)+f(Y,Z)
根据 S ∪ T = V S \cup T =V S∪T=V, { s } ∪ S ′ = S \{s\} \cup S'=S {s}∪S′=S 是可以构造求解的
-
容量性质:任意可行流 f f f, 任意割 [ S , T ] , ∣ f ∣ < = c ( S , T ) [S, T],|f| <= c(S, T) [S,T],∣f∣<=c(S,T)
-
流量性质:考虑反向边, f ( S , T ) < = c ( S , T ) f(S, T) <= c(S, T) f(S,T)<=c(S,T)
-
流量性质:对于任意可行流f,任意割[S, T],|f| = f(S, T)
最大流最小割定理
知一推二:
- 1, 可行流f是最大流
- 2,可行流f的残留网络中不存在增广路
- 3,存在某个割[S, T],|f| = c(S, T)
二,理论常见技巧
- 割没有很多可视化的图形与之对应
- 针对割的介绍一定要从定义出发
割的引申类型
- 简单割: 在有向图中割边是和源点或者汇点相连的割
- 常见割:删去割边使得源汇不联通
- 定义割:把图分成包含s的点集S和包含t的点集T,在两个集合之间的边就是割边
三,常见题型
1,代价择取
描述
小P有 n 中作物的种子,每种作物的种子有 1 个(就是可以种一棵作物)。第i种作物种植在A中种植可以获得 a_i的收益,在B中种植可以获得 b_i的收益。
由这里可以看出,对于每一株作物,仅能种在 A/B 的一块田地里,也就是二选一。
那么我们想一想最小割的做法,通俗点来说就是:对于每条路径,切去最小的那条边,以达到路径断裂且代价最小,也就是多选一。
进一步理解:对于 S->植物−>T 的一条路径,选择其中的一条边,拆掉,接着另一个就是我答案中的边。
2,打包择取
两个及以上物品同时选择产生代价
- 拆点:入点出点
- 入点向包内元素链INF边,表示在割的时候永远不会选到使得包内分开
- 由于INF,使得绝对与集合内单元素选取代价不在同一集合
2,按照已知和未知区分两个集合
给定一个无向图 G = ( V , E ) G=(V,E) G=(V,E),每个顶点都有一个标号,它是一个 [ 0 , 231 − 1 ] [0,231−1] [0,231−1] 内的整数,不同的顶点可能会有相同的标号。
对每条边 ( u , v ) (u,v) (u,v),我们定义其费用 c o s t ( u , v ) cost(u,v) cost(u,v) 为 u u u 的标号与 v v v 的标号的异或值。
现在我们知道一些顶点的标号,确定余下顶点的标号使得所有边的费用和尽可能小。
- 思路:由于是异或运算,对每一位进行最大化处理,最后合起来作为答案
- 已知的点权值是限制的,考虑讲将一部分点划分在 S 内
- 未知点是不确定的,需要不受限制的求解,考虑在 T 内,并链接INF,边,按照匹配的结果求解
- 每位建图
- 注意值域(开LL)
void build (int k)
{
Mset(h,-1);
idx = 0;
rep(i,1,m) add(p[i].x,p[i].y,1,1);
rep(i,1,n)
{
if(id[i]>=0)
{
if(id[i]>>k &1) add(i,T,INF,0);
else add(S,i,INF,0);
}
}
}
ll work ()
{
ll res = 0;
rep(i,0,30) build(i),res+= (ll)Dinic()<<i;
return res;
}
int main()
{
Mset(id,-1);
S = N-1; T = N-2;
read(n); read(m);
rep(i,1,m) read(p[i].x),read(p[i].y);
read(k);
rep(i,1,k)
{
int a,b;
read(a); read(id[a]);
}
printf("%lld",work());
return 0;
}
按照定义找到(最小)割
2,最大权闭合子图
描述 : 选定一个点集,使得点集内的点所连边不连向点集外,使得点集点权和值最大
- 虚拟源点向正(点)权点连一条容量为点权的边
- 所有负(点)权点向汇点连一条容量为点权相反数的边
- 原图中的边容量设置为正无穷(保证在构造割边的不备选)
- 答案即为:所有的正权点权值和 − - − 最小割
证明:(及其复杂,先鸽)