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

1 2 10

1 3 12

1 4 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;
}
时间: 2024-10-11 02:15:51

tyvj:1520 树的直径 spfa/树的直径的相关文章

树讲解(2)——树的输入,重心,直径

one.树的输入 1.输入每个节点父亲节点的编号 #include<vector> #include<stdio.h> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 100000 #define maxn 123456 using namespace std; int n,x,fa[N]; bool vis[N]

树的直径、树的重心与树的点分治

树的直径 树的直径(Diameter)是指树上的最长简单路. 直径的求法:两遍搜索 (BFS or DFS) 任选一点w为起点,对树进行搜索,找出离w最远的点u. 以u为起点,再进行搜索,找出离u最远的点v.则u到v的路径长度即为树的直径. 简单证明: 如果w在直径上,那么u一定是直径的一个端点.反证:若u不是端点,则从直径另一端点到w再到u的距离比直径更长,与假设矛盾. 如果w不在直径上,且w到其距最远点u的路径与直径一定有一交点c,那么由上一个证明可知,u是直径的一个端点. 如果w到最远点u

树的直径与树的重心

树的直径 树的直径是指树上的最长简单路. 直径的求法:两遍搜索 任选一点w为起点,对树进行搜索,找出离w最远的点u. 以u为起点,再进行搜索,找出离u最远的点v. 则u到v的路径长度即为树的直径. ---------------------------------------------------------------- 树的重心树的重心: 找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心. 删去重心后,生成的多棵树尽可能平衡. 树的重心可以通过简单的两次搜索求出,

【bzoj3196】 Tyvj 1730 二逼平衡树 线段树套Treap

题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查询k在区间内的后继(后继定义为大于x,且最小的数) 输入 第一行两个数 n,m 表示长度为n的有序序列和m个操作第二行有n个数,表示有序序列下面有m行,opt表示操作标号若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名若opt=2 则为操

[bzoj3932][CQOI2015]任务查询系统-题解[主席树][权值线段树]

Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行 ),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向 查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个 )的优先级之和是多少.特别的,如

跳跃表,字典树(单词查找树,Trie树),后缀树,KMP算法,AC 自动机相关算法原理详细汇总

第一部分:跳跃表 本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈"跳跃表"的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢. 跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类

【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高速光缆组成.每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络.该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信. 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略.但是由于路由器老化,在这些

从B树、B+树、B*树谈到R 树

第一节.B树.B+树.B*树 1.前言: 动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree),红黑树(Red-Black Tree ),B-tree/B+-tree/ B*-tree(B~Tree).前三者是典型的二叉查找树结构,其查找的时间复杂度O(log2N)与树的深度相关,那么降低树的深度自然会提高查找效率. 但是咱们有面对这样一个实际问题:就是大规模数据存储中,实现索引查询这样一个实际背景下,树节

Aizu 2450 Do use segment tree 树链剖分+线段树

Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show.php?pid=39566 Description Given a tree with n (1 ≤ n ≤ 200,000) nodes and a list of q (1 ≤ q ≤ 100,000) queries, process the queries in order and out