萌新求调
查看原帖
萌新求调
712680
C_yasykai楼主2022/4/13 22:07
#include<iostream>
#include<vector> 
using namespace std;

/*

求树的直径——两遍DFS 树形DP
两遍DFS:
	1.随机选择节点x作为起点,进行DFS,记录其他节点到x的距离,取与x最远的点,记作y
	2.以y为起点,重复上述操作,找到对于y最远的z
	3.此时的y与z为树的两个端点,如此求出数的直径
隐含信息:一棵树上任意一颗点最远的点一定是直径的某个端点 

*/

const int maxn=1e3+10;

int n,s,ans=maxn*1000,far;
int dis[maxn],fa[maxn],flag[maxn];

struct node{
	int to,w;
};

vector<node> G[maxn];

void dfs(int u,int f){
	fa[u]=f;
	if(dis[u]>dis[far]){
		far=u;//最远距离 
	}
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i].to,w=G[u][i].w;
		if(v==f || flag[v]){
			continue;
		}
		dis[v]=dis[u]+w;
		dfs(v,u);//下一个 
	}
}

int main(){
	cin>>n>>s;
	int u,v,w;
	n--;
	while(n--){
		cin>>u>>v>>w;
		G[u].push_back((node){v,w});
		G[v].push_back((node){u,w});
	}
	int A,B;//直径两端
	dis[1]=1;//第一次DFS 
	dfs(1,0);
	A=far; 
	dis[far]=0;//第二次DFS 
	dfs(far,0);
	B=far;
	for(int i=B,j=B;i;i=fa[i]){
		while(dis[j]-dis[i]>s){
			j=fa[j];//双指针 
		}
		int x=max(dis[B]-dis[j],dis[i]);//两端最远距离 
		ans=min(ans,x);
	} 
	for(int i=B;i!=0;i=fa[i]){
		flag[i]=1;//直径上的点跳过 
	}
	for(int i=B;i!=0;i=fa[i]){
		dis[i]=0;
		dfs(i,fa[i]);//计算最远访问距离 
	}
	for(int i=1;i<=n;i++){
		ans=max(ans,dis[i]);//计算最大值 
	}
	cout<<ans;
}

最后两个点WA

2022/4/13 22:07
加载中...