ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[可能有用科技]最小直径生成树

2022-01-30 20:01:02  阅读:259  来源: 互联网

标签:rnk int rep 绝对 最小 有用 mathcal 直径 dis


前言

NOI2021 都考了 LGV 引理,那以后难道没有那么一点(?)可能考最小直径生成树呢?

树直径与最小直径生成树

直径是图中所有最短路径的最大值.

最小直径生成树问题 :

给定一个 \(n\) 个点 \(m\) 条边的无向连通图,边有边权.

求一个生成树使得树的直径最小.

首先引入 图的绝对中心.

图的绝对中心.

图的绝对中心 是使得任何点到该中心最短路径中最大值最小的 位置.

因为绝对中心不一定是某个结点,也可以在一条边上.

然后很 \(naive\) 的想一下,这个位置似乎就是图直径的中点,所以能知道一定有至少两个到绝对中心最远的点.

然后可以发现这句话似乎只对树成立,不过后一条 一定有至少两个到绝对中心最远的点 ,这句是没问题的.

具体点 ?

3 3
1 2 1
1 3 1
2 3 1

一个环.

如果直接求图直径除以 \(2\) 那就出大问题了.

那换个想法,考虑直接枚举.

假设绝对中心在边 \((u,v)\) 上,且距离 \(u\) 点 \(x\) 单位,那么对于一个点 \(k\) , 到绝对中心的距离为 \(D = \min(\mathrm{dis}(u,k) + x,\mathrm{dis}(v,k) + (w(u,v) - x))\)

然后在这条边上尝试移动目前选择的中点的位置,可以发现画出距离 \(D\) 与当前中心到 \(u\) 距离 \(x\) 的函数图像是一条折线.

那么就是需要在这些折线里找到最小的就能得到绝对中心了.

类似这样一种感觉 :

然后可以发现这个过程经常需要快速取距离某个点最远的结点这样的操作.

于是定义 \(\mathrm{rnk}(u,k)\) 为距离 \(u\) 第 \(k\) 远的结点.

可以 \(\mathcal{O} (n^2 \log n)\) 求出.

然后是具体的算法流程.

  • 全源最短路 (\(\mathcal{O} (n^3)\) 或 \(\mathcal{O}(nm \log m)\))

  • 求 \(\mathrm{rnk}\), \(\mathcal{O}(n^2 \log n)\)

  • 枚举点作为绝对中心 \(\min_{i = 1}^{n} \{\mathrm{dis}(i,\mathrm{rnk}(i,n))\}\),\(\mathcal{O}(n)\)

  • 枚举边上的位置作为绝对中心,从最远的向最近找,直到出现转折点,\(\mathcal{O}(n^2)\)

总体复杂度基本就是巨大常数 \(\mathcal{O}(n^3)\) 的水平.

CF266D BerDonalds

Code :

struct Edge {
	int st,ed,w;
}e[M];

int n,m;
int dis[N][N];
int rnk[N][N];
int val[N];

inline bool cmp(int a,int b) {
	return val[a] < val[b];
}

void Centro() {
	rep(k,1,n) rep(i,1,n) rep(j,1,n)
		dis[i][j] = std::min(dis[i][j],dis[i][k] + dis[k][j]);
	rep(i,1,n) {
		rep(j,1,n) {
			rnk[i][j] = j;
			val[j] = dis[i][j];
		}
		std::sort(rnk[i] + 1,rnk[i] + n + 1,cmp);
	}
	int ans = INF;
	rep(i,1,n)
		ans = std::min(ans,dis[i][rnk[i][n]] * 2);
	rep(i,1,m) {
		int u = e[i].st,v = e[i].ed,w = e[i].w;
		int pos = n;
		repb(i,n - 1,1) if(dis[v][rnk[u][i]] > dis[v][rnk[u][pos]]) {
			ans = std::min(ans,dis[u][rnk[u][i]] + dis[v][rnk[u][pos]] + w);
			pos = i;
		}
	}
	write_db(ans / 2.0,2),enter;
}

求解最小直径生成树

首先求出绝对中心.

然后分类讨论 :

绝对中心在某个结点的情况

从该点向外求最短路树即可.

绝对重心在某条边上

考虑在那条边上建一个虚拟结点,分别向那条边两个端点连边,然后求最短路径树,输出时不输出虚拟节点即可.

SP735 MDST - Minimum Diameter Spanning Tree

SP1479 PT07C - The GbAaY Kingdom

没有代码,因为我发现,求解最小直径生成树是在绝对中心不假,但是求最短路径树完全是扯淡...

参见这篇论文

等我看懂了就到 OI-wiki 上去 Pull Request 吧...

标签:rnk,int,rep,绝对,最小,有用,mathcal,直径,dis
来源: https://www.cnblogs.com/AstatineAi/p/Minimum-Diameter-Spanning-Tree.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有