最小割树

考试考了,发现自己不会,所以写一下。

最小割树(Gomory−HuTree) 为一颗有 \(n\) 个点的带边权树,满足对于任意两点 \((u,v)\) ,满足其在树上的瓶颈路为原图中两点之间的最小割(最大流)。

建立方法如下:

  1. 在点集 \(S\) (初始时为1~n) 中取两点 \(s,t\) ,计算其原图上最小割(最大流),记为 \(cut(s,t)\)

  2. 找到包含 \(s\) 的割集(残量网络中的连通分量)\(U\) ,包含 \(t\) 的割集 \(V\)

  3. 在树上加入一条 \((u,v)\) 之间的边,边权为 \(cut(s,t)\)

  4. 对点集 \(U\)\(V\) 递归的进行操作

这样来看,总共会做 \(n-1\) 次最小割,复杂度为 \(O(n^3m)\) 。不过由于 Dinic 算法特殊的复杂度,遇到问题时一般要特殊分析。

下面我们要证明这个过程是对的,也就是说对于 \(s\)\((s,t)\) 割中所在的割集 \(W\)\(u,v \in W\) ,\(X\)\((u,v)\) 割中 \(u\) 所在的割集,证明存在一种割的方式使得 \(X \subset W\)

定义 \(c(x)\) 表示所有仅有一个端点\(x\) 中的边权和,可以观察到有若干性质:

\[c(A)+c(B) \geq c(A \cup B) + c(A \cap B) \]

\[c(A)+c(B) \geq c(A \setminus B) + c(B \setminus A) \]

情况1: \(t \not \in X\)

由于 \(c(X)+c(W) \geq c(X \cup W) + c(X \cap W)\)

\(c(X \cup W)\) 是一个 \((s,t)\) 割,所以 \(c(X \cup W) \geq c(W)\)

\(c(X \cap W)\) 是一个 \((u,v)\) 割,所以 \(c(X \cap W) \geq c(X)\)

所以 \(c(X \cap W) = c(X)\)

情况2: \(t \in X\)

由于 \(c(X)+c(W) \geq c(X \setminus W) + c(W \setminus X)\)

\(c(X \setminus W)\) 是一个 \((s,t)\) 割,所以 \(c(X \setminus W) \geq c(W)\)

\(c(W \setminus X)\) 是一个 \((u,v)\) 割,所以 \(c(W \setminus X) \geq c(X)\)

所以 \(c(W \setminus X) = c(X)\)

宗上,总是有一种方法满足 \(X \subset W\)

同时,我们也证明了对于一个 \(n\) 的图,会有 \(n-1\) 中值不同的最小割。

应用:

多次求最大流(最小割)

建最小割树,然后转化成树上的路径 \(\min\) ,就能直接维护。

模板:

void mark(int x){
	//cout<<x<<endl;
	vis[x]=true;
	for(int i=head[x];i!=-1;i=edge[i].nxt){
		int to=edge[i].to;
		if(edge[i].cap>edge[i].flow&&!vis[to]){
			mark(to);
		}
	}
}

void solve(vector<int > S){
	if(S.size()==1)return;
	tNode=0;
	for(int i=1;i<=n;i++)head[i]=-1;
	for(int i=0;i<nedge.size();i++){
		cedge cur=nedge[i];
		addE(cur.u,cur.v,cur.c);
		addE(cur.v,cur.u,0);
	}
	s=S[0];
	t=S[1];
	int cut=DINIC();
	sum+=cut;
	tree[s].push_back(mk(cut,t));
	tree[t].push_back(mk(cut,s));
	memset(vis,false,sizeof(vis));
	mark(s);
	vector<int > U,M;
	for(int i=0;i<S.size();i++){
		if(vis[S[i]])U.push_back(S[i]);
		else M.push_back(S[i]);
	}
	solve(U);
	solve(M);
}

例题:Pumping Stations

题解一会写

记得补充图片

posted @ 2023-10-12 15:22  _hjy  阅读(58)  评论(0)    收藏  举报