「学习笔记」树的直径

树的直径

定义

树的直径为树上最长的路径 δ(u,v) (u,vV).\delta (u,v) \ ( u,v \in V ).

实现

可先从任意一点 aa 出发,找离它最远的点 bb,再从点 bb 出发,找离它最远的点 ccδ(b,c)\delta(b,c) 即为树的直径。

证明如下:

  • aa 已经在直径上,可知 bb 也在直径上且为直径的一个端点;
  • aa 不在直径上,用反证法进行证明。
    假设此时 δ(b,c)\delta(b,c)不是直径,δ(p,q)\delta(p,q) 是直径,
    • δ(p,q)\delta(p,q)δ(a,b)\delta(a,b) 有交点 cc,由于 aabb 距离是最远的,那么 δ(a,c)+δ(b,c)>δ(a,c)+δ(c,p)\delta(a,c)+\delta(b,c)>\delta(a,c)+\delta(c,p),故 δ(b,c)>δ(c,p)\delta(b,c)>\delta(c,p),由此可得 δ(b,c)+δ(c,q)>δ(c,p)+δ(c,q)\delta(b,c)+\delta(c,q)>\delta(c,p)+\delta(c,q),即 δ(b,q)>δ(p,q)\delta(b,q)>\delta(p,q),与 δ(p,q)\delta(p,q) 是直径矛盾,故不成立;
    • δ(p,q)\delta(p,q)δ(a,b)\delta(a,b) 无交点,m,nm,n 分别为 δ(p,q)\delta(p,q)δ(a,b)\delta(a,b) 上一点。可得 δ(a,n)+δ(b,n)>δ(b,n)+δ(m,n)+δ(m,q)\delta(a,n)+\delta(b,n)>\delta(b,n)+\delta(m,n)+\delta(m,q),同时减掉 δ(b,n)\delta(b,n),得 δ(a,n)>δ(m,n)+δ(m,q)\delta(a,n)>\delta(m,n)+\delta(m,q),可得 δ(a,n)+δ(m,n)>δ(m,q)\delta(a,n)+\delta(m,n)>\delta(m,q) ,同时加上 δ(m,p)\delta(m,p)δ(a,n)+δ(m,n)+δ(m,p)>δ(m,q)+δ(m,p)\delta(a,n)+\delta(m,n)+\delta(m,p)>\delta(m,q)+\delta(m,p),即 δ(a,n)+δ(m,n)+δ(m,p)>δ(p,q)\delta(a,n)+\delta(m,n)+\delta(m,p)>\delta(p,q) ,与 δ(p,q)\delta(p,q) 是直径矛盾,故也不成立。

得证。

code:

//求路径
void dfs(int x , int father) {
	for (r_ int i=head[x]; i; i=edge[i].next) {
		int u=edge[i].to;
		
		if (u==father) continue;
		
		fa[u]=x;
		dis[u]=dis[x]+edge[i].data;
		
		dfs(u , x);
	}
}

int main() {
	read(n);
	for (r_ int i=1; i<n; i++) {
		ll x , y , z;
		read(x , y , z);
		add(x , y , z); add(y , x , z);
	}
	
	//处理两遍路径得出树的直径
	dfs(1 , 0);
	
	for (r_ int i=1; i<=n; i++) {
		if (dis[i]>Max) {Max=dis[i]; s=i;}
		dis[i]=0;
	}
	
	dfs(s , 0);
	
	Max=-0x7FFFFFFF;
	for (r_ int i=1; i<=n; i++) {
		if (dis[i]>Max) {Max=dis[i]; t=i;}
	}
	
	return 0;
}

例题:SDOI2013「直径」Solution

posted @ 2020-08-03 22:17  willbe233  阅读(46)  评论(0)    收藏  举报