Lightoj 1094 【DFS】

题意:
给你一颗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;
}





原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777541.html