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;

}

 

你可能感兴趣的:(SPFA)