首先把无向图变成一棵树,直径肯定由叶子组成

有以下两种情况

第一种经过根节点,则找两个最远的叶子肯定是直径,也就是B+D。

第二种不经过根节点,则目标的两个叶子肯定有一个不为根的公共祖先,如红点O,则在红点O下面找两个最远的叶子作为直径,找到了C+F。而很明显,这两个目标叶子中的其中一个(F)是距离根最远的叶子,因为如果两个叶子中不包含离根最远的点,则F经过根节点会找到更长的直径,矛盾。

树的直径必然包括一个最远(深)叶子。先搜索到这个点(F),然后再搜索一次最远的点,可以得到树的直径。

这也说明,若把每个点(X)当成一个根,则直径的两个点(C+F)中的一个为X的最远点 ,所以找到直径C+F,则可以找到每个点在无向图中的最远距离:disCX or disFX

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
using namespace std;
int dis[],ans[];
int n,s,t;
vector<int>G[];
vector<int>L[];
void _dfs(int v)
{
for(int i=;i<G[v].size();i++){
if(!dis[G[v][i]]) {
dis[G[v][i]]=dis[v]+L[v][i];
_dfs(G[v][i]);
}//任意两个点只有一条路,所以dfs和bfs效果一样
}
}
void _finds()
{
memset(dis,,sizeof(dis));
dis[]=;_dfs();s=;
for(int i=;i<=n;i++)
if(dis[i]>dis[s]) s=i; }
void _findt()
{
memset(dis,,sizeof(dis));
dis[s]=;_dfs(s);t=;
for(int i=;i<=n;i++)
if(dis[i]>dis[t]) t=i;
for(int i=;i<=n;i++) ans[i]=dis[i]-;
}
void _tdis()
{
memset(dis,,sizeof(dis));
dis[t]=;
_dfs(t);
for(int i=;i<=n;i++)
if(dis[i]->ans[i]) ans[i]=dis[i]-;
}
int main()
{
int i,j,k,u,v;
while(~scanf("%d",&n)){
for(i=;i<=n;i++) {
G[i].clear();
L[i].clear();
}
for(i=;i<=n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(i);
L[u].push_back(v);
G[i].push_back(u);
L[i].push_back(v);
}
_finds();
_findt();
_tdis();
for(i=;i<=n;i++)
printf("%d\n",ans[i]);
}
return ;
}

树的直径证明+HDU2196的更多相关文章

  1. 「树的直径」BFS方法证明

    选定任意一个点u,从u开始BFS求出距离u最大的点s,再从s点出发BFS到距离s最大的点t,则dis(s,t)即为树的直径 证明 其实只要找到了树的直径的一个端点,再BFS找到最远点就一定是直径的另一 ...

  2. 树的直径的求法即相关证明【树形DP || DFS】

    学习大佬:树的直径求法及证明 树的直径 定义: 一棵树的直径就是这棵树上存在的最长路径. 给定一棵树,树中每条边都有一个权值,树中两点之间的距离定义为连接两点的路径边权之和.树中最远的两个节点之间的距 ...

  3. hdu2196 树的直径 + bfs

    //Accepted 740 KB 15 ms //树的直径 //距离一个顶点最远的点一定是树的直径的一个端点 #include <cstdio> #include <cstring ...

  4. poj2631 求树的直径裸题

    题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: ...

  5. [USACO2004][poj1985]Cow Marathon(2次bfs求树的直径)

    http://poj.org/problem?id=1985 题意:就是给你一颗树,求树的直径(即问哪两点之间的距离最长) 分析: 1.树形dp:只要考虑根节点和子节点的关系就可以了 2.两次bfs: ...

  6. BZOJ 2282 & 树的直径

    SDOI2011的Dayx第2题 题意: 在树中找到一条权值和不超过S的链(为什么是链呢,因为题目中提到“使得路径的两端都是城市”,如果不是链那不就不止两端了吗——怎么这么机智的感觉...),使得不在 ...

  7. HDU 4123(树的直径+单调队列)

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. CF 120F Spider 树的直径 简单题

    一个男孩有n只玩具蜘蛛,每只蜘蛛都是一个树的结构,现在男孩准备把这n只小蜘蛛通过粘贴节点接在一起,形成一只大的蜘蛛.大的蜘蛛也依然是树的结构.输出大的蜘蛛的直径. 知识: 树的直径是指树上的最长简单路 ...

  9. POJ 1985 Cow Marathon && POJ 1849 Two(树的直径)

    树的直径:树上的最长简单路径. 求解的方法是bfs或者dfs.先找任意一点,bfs或者dfs找出离他最远的那个点,那么这个点一定是该树直径的一个端点,记录下该端点,继续bfs或者dfs出来离他最远的一 ...

随机推荐

  1. java基础知识面试题(1-40)

    1.面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:- 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些 ...

  2. 应用连接mysql8.0注意事项

    mysql8.0在安装过程中会让你选择一个Authentication Method,如果你选择上面的更强的授权机制,那么就会出现下面的情况 图片来源:https://blog.csdn.net/qq ...

  3. 【运维技术】kafka三实例集群环境搭建及测试使用

    kafka三实例集群环境搭建及测试使用 单机搭建分为两部分:1. 软件安装启动 2. 软件配置 软件安装启动: # 切换到目录 cd /app # 获取kafka最新安装包,这边使用的是镜像地址,可以 ...

  4. 一个Golang例子:for + goroutine + channel

    Rob Pike 在 Google I/O 2012 - Go Concurrency Patterns 里演示了一个例子(daisy chain). 视频地址:https://www.youtube ...

  5. 实验三 敏捷开发与XP实践20145204和20145236

    实验三 敏捷开发与XP实践20145204和20145236 实验名称 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 学会使用git 学会代码的重构 实现团队合作 团队分工 20145204: ...

  6. numpy数组广播

    numpy数组的广播功能强大,但是也同时让人疑惑不解,现在让我们来谈谈其中的原理. 广播原则: 如果两个数组的后缘维度(即:从末尾开始算起的维度)的轴长相符或其中一方的长度为1,则认为它们是广播兼容的 ...

  7. Linux下停止没有关闭的远程登陆终端

    脚本如下: #!/bin/shTTY_LOG=tty_logTTY_LOG1=tty_log1USER_NAME=`whoami`#echo ${USER_NAME}who|grep ${USER_N ...

  8. 通过代码来操作SQLite的示例

    Getting started with SQLite in C# http://blog.tigrangasparian.com/2012/02/09/getting-started-with-sq ...

  9. 【bzoj4972】小Q的方格纸 前缀和

    题目让O(1)预处理出来 类三角形边界及内部的和 根据这个图 就是一个大矩形-左边的绿色的矩形 - 蓝色的大三角形 + 右上角突出的蓝色的小三角形 #include<bits/stdc++.h& ...

  10. python应用-随机漫步

    对python应用的一个巩固,以及熟悉matplotlib的用法 效果如下: # -*- coding: utf-8 -*- """ Created on Fri Sep ...