给你一颗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 ",cas++,res); } return 0; }