【题解】P7516 [省选联考 2021 A/B 卷] 图函数 动态传递闭包 最短路

题目链接

题意可转化为:只考虑前 \(i\) 条边构成的图 \(G_i\) ,对于每个点 \(u\) 有多少点 \(v\) 满足只经过大于 \(\min(u,v)\) 的点两个点互相可达。

对于一个固定的图 \(G_i\) ,我们可以通过 \(\text{floyd}\) 通过更新顺序维护 “动态加点” 的传递闭包。

类似 只有加边的动态传递闭包 ,考虑建一张新的带权图,维护点 \(u\) 到达点 \(v\) 至少需要加多少条边,因为具有单调性所以若图 \(G_i\) 使 \(u\) 可达 \(v\) ,那么图 \(G_j,j > i\) 一定能够使得 \(u\) 可达 \(v\)

那么我们这样就可以很容易地维护出点对 \((u,v)\) 对哪些图 \(G_i\) 有贡献。

即本质上,这种做法可以维护出的是点对 \((u,v)\) 对哪些版本的图有贡献。

可以在 \(O(n^3)\)\(O(nm\log n)\) 的时间内维护出。

对于 \(\text{floyd}\) 有一个卡常小技巧:

for (int x = n; x >= 1; x--) {
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= (i>x?x:n); j++)
			f[i][j] = std::max(f[i][j],std::min(f[i][x],f[x][j]));
}

即对于后续的更新用不到集合 \([x,n]\) 点之间的最短路。

代码地址

posted @ 2021-09-07 17:26  Themaxmaxmax  阅读(78)  评论(0编辑  收藏  举报