码迷,mamicode.com
首页 > 其他好文 > 详细

tyvj:1520 树的直径 spfa/树的直径

时间:2015-03-30 20:37:17      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

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;
}

 

tyvj:1520 树的直径 spfa/树的直径

标签:

原文地址:http://www.cnblogs.com/qscqesze/p/4378809.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!