题目描述:

点这里

题目大意:

就是在一个树上找其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。

题解:

首先,第一问很好求,两边dfs就行了,第一次从任一点找距它最远的点,再从这个点找距它的最远点,后两个点就是树的直径的两个端点,证明就不赘述了,有兴趣可以自己证一证玩一玩。

那第二问怎么办呢?假设我们有这样一个图(如下)

如图所示,中间那根直的就是树的直径之一,旁边标红的也是树的直径。(图画的不好,感性理解)

我们要知道,树的直径是必定会有交叉的,可以画个图自己看一下。

所以就会有一个想法:首先找出一条直径的起点,向终点推,如果碰到交叉,就看这个交叉是否是直径,如果是,就把第一个直径收缩,再继续找。再从终点向起点收缩一遍。剩下的边就是题目中要求的了。

最后就是代码实现了,收缩的过程是真滴玄学。

代码如下:

#include<iostream>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define rint register int
#define M 200005
using namespace std;
inline int read()
{
int s=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+ch-'';ch=getchar();}
return s*f;
}
inline ll max(ll a,ll b){return a>b?a:b;}
ll dis[M],maxx,s,t;
ll n,m,cnt,head[M],vis[M];
ll dep[M],father[M],l,r,ans,son[M];
struct edge
{
int to,nex,v;
}e[M<<];
inline void add(int u,int v,int w)
{
e[++cnt].to=v;
e[cnt].v=w;
e[cnt].nex=head[u];
head[u]=cnt;
}
void dfs(int u,int fa)
{
for(rint i=head[u];i;i=e[i].nex)
{
int v=e[i].to;if(v==fa) continue;father[v]=u;
dis[v]=dis[u]+e[i].v;dfs(v,u);
}
}
void find(int u,int fa)
{
dep[u]=;ll maxn=;
for(rint i=head[u];i;i=e[i].nex)
{
int v=e[i].to;if(v==father[u] || vis[v]==) continue;
find(v,u);maxn=max(maxn,dep[v]+e[i].v);
}
dep[u]=maxn;
}
int main()
{
n=read();
for(rint i=;i<=n-;++i)
{
int x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
}
dfs(,);
for(rint i=;i<=n;++i)
{
if(dis[i]>maxx) maxx=dis[i],s=i;
dis[i]=;
}
dfs(s,);maxx=;
for(rint i=;i<=n;++i)
{
if(dis[i]>maxx) maxx=dis[i],t=i;
}
printf("%lld\n",maxx);
int l=t,r=s,now=t;
while(now!=s)
{
vis[now]=;
son[father[now]]=now;
now=father[now];
}
now=t;
while(now!=s)
{
dep[now]=;
find(now,);
if(dep[now]==maxx-dis[now]) l=now;
now=father[now];
}
now=s;
while(now)
{
find(now,);
if(dep[now]==dis[now]) r=now;
now=son[now];
}
while(l!=r && l)
{
l=father[l];
++ans;
}
printf("%lld\n",ans);
return ;
}

谢谢大家!

SDOI2013直径(树的直径)的更多相关文章

  1. POJ 1985.Cow Marathon-树的直径-树的直径模板(BFS、DFS(vector存图)、DFS(前向星存图))

    Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 7536   Accepted: 3559 Case ...

  2. [SDOI2013]直径 (树的直径,贪心)

    题目链接 Solution 我们直接找到一条直径 \(s\),起点为 \(begin\),终点为 \(end\). 从前往后遍历点 \(u\) ,若子树中最大的距离与 \(dis(u,begin)\) ...

  3. 树形DP 学习笔记(树形DP、树的直径、树的重心)

    前言:寒假讲过树形DP,这次再复习一下. -------------- 基本的树形DP 实现形式 树形DP的主要实现形式是$dfs$.这是因为树的特殊结构决定的——只有确定了儿子,才能决定父亲.划分阶 ...

  4. BZOJ3124 [Sdoi2013]直径 【树的直径】

    题目 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一棵树上,任意两个节 ...

  5. poj2631 求树的直径裸题

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

  6. poj1985 Cow Marathon (求树的直径)

    Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 3195   Accepted: 1596 Case ...

  7. VIJOS1476旅游规划[树形DP 树的直径]

    描述 W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流.但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员.具体说来,W市的交通网络十分简单,它包 ...

  8. poj2631 树的直径

    设s-t是这棵树的直径,那么对于任意给予的一点,它能够到达的最远的点是s或者t. 这样我们可以通过2次bfs找到树的直径了. #include<cstdio> #include<qu ...

  9. 【BZOJ-1912】patrol巡逻 树的直径 + DFS(树形DP)

    1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1034  Solved: 562[Submit][St ...

随机推荐

  1. Java设计模式学习01——单例模式(转)

    原地址:http://blog.csdn.net/xu__cg/article/details/70182988 Java单例模式是一种常见且较为简单的设计模式.单例模式,顾名思义一个类仅能有一个实例 ...

  2. 在struts2.3.4.1中使用注解、反射、拦截器实现基于方法的权限控制

    权限控制是每一个系统都应该有的一个功能,有些只需要简单控制一下就可以了,然而有些却需要进行更加深入和细致的权限控制,尤其是对于一些MIS类系统,基于方法的权限控制就更加重要了. 用反射和自定义注解来实 ...

  3. 认识Echarts(网址:http://echarts.baidu.com/tutorial.html#ECharts%20%E7%89%B9%E6%80%A7%E4%BB%8B%E7%BB%8D)

    first.html: <!DOCTYPE html><html lang="en"><head> <meta charset=" ...

  4. H5/

    1.value: 2.selected="selected": 设置selected="selected"属性,则该选项就被默认选中. 下拉列表也可以进行多选操 ...

  5. Linux版本信息如何查询

    1.输入"uname -a ",可显示电脑以及操作系统的相关信息.2.输入"cat /proc/version",说明正在运行的内核版本.3.输入"c ...

  6. PHP微信授权登录信息

    文件1:index.php //换成自己的接口信息 $appid = 'XXXXX'; header('location:https://open.weixin.qq.com/connect/oaut ...

  7. 226. Invert Binary Tree 翻转二叉树

    [抄题]: Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 [暴力解法]: 时间分析: 空间分 ...

  8. sqlserver服务器硬件性能瓶颈分析

    硬件性能瓶颈 内存 内存对SQL Server性能的影响胜过任何其他硬件.因此,对SQL Server系统的内存使用情况进行定期监视以确保内存的可用百分比高于20%是很有必要的.如果用户遭遇性能问题, ...

  9. [GO]二进制文件的拷贝

    writestring的方式只适用于字符串的写入,对于十进制文件的写入只要使用write就可以了 package main import ( "os" "fmt" ...

  10. 39 编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n(利用指针函数)

    题目:编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n(利用指针函数) public class _039PrintFu ...