【学习笔记】树的直径

定义

树的直径定义为树上任意两点间最长的简单路径

求法1:两次dfs

适用范围:树上所有边边权都非负

算法过程:

以树上任意一点开始第一次dfs,找到距其最远的点\(z\),再以\(z\)为起始点进行第二次dfs,找到距其最远的点\(z\prime\),则\(zz\prime\)即为所求。

代码:

void Dfs(int x,int fa,int dis) {
	if(dis > mmax) {
		mmax = dis;
		flag = x;
	}
	for(auto i:E[x]) {
		if(i.first == fa) continue;
		Dfs(i.first,x,dis + i.second);
	}
}
void SolveDiameterOfTree() {
	mmax = 0;
	flag = 0;
	Dfs(1,0,0);
	int z = flag;
	//cout << z << "\n";
	mmax = 0;
	flag = 0;
	Dfs(z,0,0);
	int zp = flag;
	z1 = z;
	zp1 = zp;
}

例题

P6722「MCOI-01」Village 村庄

首先注意到有二分图必有奇环。

同时由于这张图的特殊构造,有奇环必有三元环。

同时,该三元环必包含直径的两个端点。

那么枚举剩下的一个点,判断该三元环是否符合要求即可。

代码:

#include<iostream>
#include<vector>
using namespace std;
int dis1[100010],dis2[100010],t,n,k,x,y,v,mmax,flag,z1,zp1;
vector<pair<int,int> > E[100010];
void Dfs(int x,int fa,int dis) {
	if(dis > mmax) {
		mmax = dis;
		flag = x;
	}
	for(auto i:E[x]) {
		if(i.first == fa) continue;
		Dfs(i.first,x,dis + i.second);
	}
}
void Dfs2(int x,int fa,int dis) {
	dis1[x] = dis;
	for(auto i:E[x]) {
		if(i.first == fa) continue;
		Dfs2(i.first,x,dis + i.second);
	}
}
void Dfs3(int x,int fa,int dis) {
	dis2[x] = dis;
	for(auto i:E[x]) {
		if(i.first == fa) continue;
		Dfs3(i.first,x,dis + i.second);
	}
}
void SolveDiameterOfTree() {
	mmax = 0;
	flag = 0;
	Dfs(1,0,0);
	int z = flag;
	//cout << z << "\n";
	mmax = 0;
	flag = 0;
	Dfs(z,0,0);
	int zp = flag;
	z1 = z;
	zp1 = zp;
}
void CalcDis1(int z1) {
	Dfs2(z1,0,0);
}
void CalcDis2(int zp1) {
	Dfs3(zp1,0,0);
}
int main()
{
	cin >> t;
	loop:while(t--) {
		cin >> n >> k;
		for(int i = 1;i <= n;i++) {
			E[i].clear();
		}
		for(int i = 1;i <= n - 1;i++) {
			cin >> x >> y >> v;
			E[x].push_back({y,v});
			E[y].push_back({x,v});
		}
		SolveDiameterOfTree();
		//cout << z1 << " " << zp1 << "\n";
		CalcDis1(z1);
		CalcDis2(zp1);
		for(int i = 1;i <= n;i++) {
			//cout << dis1[i] << " " << dis2[i] << "\n";
			if(dis1[i] >= k && dis2[i] >= k) {
				cout << "Baka Chino" << "\n";
				goto loop;
			}
		}
		cout << "Yes" << "\n";
	}
}
posted @ 2023-11-09 20:10  IANYEYZ  阅读(11)  评论(0编辑  收藏  举报