题意:
给你一颗n-1条边的树,求某两点的最长路
思路:
随便找个根,然后我们从根往下搜,对于每个结点会出现多个子节点或者一个子节点或者没有结点,
多个子节点的话,就以他为中间点,在子节点中找两条最长的,加起来比比;
直接搜吧;
给你一颗n-1条边的树,求某两点的最长路
思路:
随便找个根,然后我们从根往下搜,对于每个结点会出现多个子节点或者一个子节点或者没有结点,
多个子节点的话,就以他为中间点,在子节点中找两条最长的,加起来比比;
直接搜吧;
哎好难讲啊,其实画个图就很容易了;(直接注释在代码里面吧。。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=3e4+10;
struct Edge{
int to;
int w;
int next;
};
Edge q[N*2];
int head[N*2],tol;
int n;
bool vis[N*2];
//初始化
void init()
{
tol=0;
memset(head,-1,sizeof(head));
}
//建边
void add(int u,int v,int w)
{
q[tol].to=v;
q[tol].w=w;
q[tol].next=head[u];
head[u]=tol++;
}
int res;//答案
int dfs(int u) //dfs是返回根节点到一个子节点的最长长度
{
int tep1,tep2; //取每个根结点连出去的两个最大值,*默认有两个,只有一个/没有的时候返回不就是最小/0嘛
tep1=tep2=0;
for(int i=head[u];i!=-1;i=q[i].next)
{
int to=q[i].to;
if(!vis[to])
{
vis[to]=1;
int temp=q[i].w+dfs(to); //每次拿过来和最小的两个比较
if(temp>tep1)
{
tep2=tep1;
tep1=temp;
}
else if(temp>tep2)
tep2=temp;
}
}
res=max(res,tep1+tep2); //有可能存在以中间子节点作为根节点,然后他的两个子节点最远
return tep1;
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
int u,v,w;
scanf("%d",&n);
init();
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
res=0;
memset(vis,0,sizeof(vis));
vis[0]=1;
dfs(0);
printf("Case %d: %d\n",cas++,res);
}
return 0;
}