zoukankan      html  css  js  c++  java
  • tyvj:1520 树的直径 spfa/树的直径

    tyvj:1520 树的直径

    Time Limit: 1 Sec  Memory Limit: 131072KiB
    Submit: 9619  Solved: 3287

    题目连接

    http://www.tyvj.cn/p/1520

    Description

    树的直径,即这棵树中距离最远的两个结点的距离。每两个相邻的结点的距离为1,即父亲结点与儿子结点或儿子结点与父子结点之间的距离为1.有趣的是,从树 的任意一个结点a出发,走到距离最远的结点b,再从结点b出发,能够走的最远距离,就是树的直径。树中相邻两个结点的距离为1。你的任务是:给定一棵树, 求这棵树中距离最远的两个结点的距离。

    Input

    输入共n行
    第一行是一个正整数n,表示这棵树的结点数
    接下来的n-1行,每行三个正整数a,b,w。表示结点a和结点b之间有一条边,长度为w
    数据保证一定是一棵树,不必判错

    Output

    输出共一行
    第一行仅一个数,表示这棵树的最远距离

    Sample Input

    4
    10
    12
    15

    Sample Output

    27

    HINT

    10%的数据满足1<=n<=5
    40%的数据满足1<=n<=100
    100%的数据满足1<=n<=10000 1<=a,b<=n 1<=w<=10000

    题解:

    随便拿一个点进行spfa,然后找到离这个点最远的点,又进行一次spfa,然后这个点所得到的最远点,那么这个距离,就是树的直径

    不要问我怎么知道这个结论的,我也不知道我怎么知道的……

    记住就好……

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200001
    #define mod 10007
    #define eps 1e-9
    //const int inf=0x7fffffff;   //无限大
    const int inf=0x3f3f3f3f;
    /*
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    */
    //**************************************************************************************
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    struct edge
    {
        int x,y;
    };
    struct node
    {
        int x,y;
    };
    vector<edge> kiss[maxn];
    void add_edge(int a,int b,int c)
    {
        kiss[a].push_back((edge){b,c});
        kiss[b].push_back((edge){a,c});
    }
    int vis[maxn];
    int dis[maxn];
    int main()
    {
        int n;
        n=read();
        for(int i=0;i<n-1;i++)
        {
            int a,b,c;
            a=read(),b=read(),c=read();
            add_edge(a,b,c);
        }
        queue<int> q;
        q.push(1);
        for(int i=1;i<=n;i++)
            dis[i]=inf;
        dis[1]=0;
        int ans=0;
        int ans1=0;
        memset(vis,0,sizeof(vis));
        vis[1]=1;
        while(!q.empty())
        {
            int now=q.front();
            vis[now]=0;
            q.pop();
            for(int i=0;i<kiss[now].size();i++)
            {
                int next=kiss[now][i].x;
                //cout<<dis[now]+kiss[now][i].y<<" "<<dis[next]<<endl;
    
                if(dis[now]+kiss[now][i].y<dis[next])
                {
                    dis[next]=dis[now]+kiss[now][i].y;
                    if(vis[next]==0)
                    {
                        vis[next]=1;
                        q.push(next);
                    }
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(dis[i]!=inf&&dis[i]>ans1)
            {
                ans=i;
                ans1=dis[i];
            }
        }
        for(int i=1;i<=n;i++)
            dis[i]=inf;
        dis[ans]=0;
        memset(vis,0,sizeof(vis));
        q.push(ans);
        vis[ans]=1;
        ans=0;
        ans1=0;
        while(!q.empty())
        {
            int now=q.front();
            vis[now]=0;
            q.pop();
            for(int i=0;i<kiss[now].size();i++)
            {
                int next=kiss[now][i].x;
                if(dis[now]+kiss[now][i].y<dis[next])
                {
                    dis[next]=dis[now]+kiss[now][i].y;
                    if(vis[next]==0)
                    {
                        vis[next]=1;
                        q.push(next);
                    }
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(dis[i]!=inf)
                ans1=max(ans1,dis[i]);
        }
        cout<<ans1<<endl;
    }
  • 相关阅读:
    HDU 1540 Tunnel Warfare (线段树区间合并)
    P2258 子矩阵
    P5021 赛道修建
    P4084 [USACO17DEC]Barn Painting
    P3914 染色计数
    比赛用模板
    P3594 [POI2015]WIL-Wilcze doły
    P5022 旅行
    P3952 时间复杂度
    P3960 列队
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4378809.html
Copyright © 2011-2022 走看看