SDOI2013直径(树的直径)
题目描述:
题目大意:
就是在一个树上找其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。
题解:
首先,第一问很好求,两边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直径(树的直径)的更多相关文章
- POJ 1985.Cow Marathon-树的直径-树的直径模板(BFS、DFS(vector存图)、DFS(前向星存图))
Cow Marathon Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 7536 Accepted: 3559 Case ...
- [SDOI2013]直径 (树的直径,贪心)
题目链接 Solution 我们直接找到一条直径 \(s\),起点为 \(begin\),终点为 \(end\). 从前往后遍历点 \(u\) ,若子树中最大的距离与 \(dis(u,begin)\) ...
- 树形DP 学习笔记(树形DP、树的直径、树的重心)
前言:寒假讲过树形DP,这次再复习一下. -------------- 基本的树形DP 实现形式 树形DP的主要实现形式是$dfs$.这是因为树的特殊结构决定的——只有确定了儿子,才能决定父亲.划分阶 ...
- BZOJ3124 [Sdoi2013]直径 【树的直径】
题目 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一棵树上,任意两个节 ...
- poj2631 求树的直径裸题
题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: ...
- poj1985 Cow Marathon (求树的直径)
Cow Marathon Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 3195 Accepted: 1596 Case ...
- VIJOS1476旅游规划[树形DP 树的直径]
描述 W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流.但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员.具体说来,W市的交通网络十分简单,它包 ...
- poj2631 树的直径
设s-t是这棵树的直径,那么对于任意给予的一点,它能够到达的最远的点是s或者t. 这样我们可以通过2次bfs找到树的直径了. #include<cstdio> #include<qu ...
- 【BZOJ-1912】patrol巡逻 树的直径 + DFS(树形DP)
1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1034 Solved: 562[Submit][St ...
随机推荐
- jquery中绑定click事件重复执行问题
jquery中单击事件重复多次执行的问题使用如下方式: $('#sub').unbind('click').click(function () { ... });
- canvas的性能优化
canvas玩多了后,就会自动的要开始考虑性能问题了.怎么优化canvas的动画呢? [使用缓存] 使用缓存也就是用离屏canvas进行预渲染了,原理很简单,就是先绘制到一个离屏canvas中,然后再 ...
- 【原】Coursera—Andrew Ng机器学习—Week 8 习题—聚类 和 降维
[1]无监督算法 [2]聚类 [3]代价函数 [4] [5]K的选择 [6]降维 Answer:本来是 n 维,降维之后变成 k 维(k ≤ n) [7] [8] Answer: 斜率-1 [9] A ...
- 一条跨库更新数据的sql
UPDATE [db1].[dbo].[R_ResAndBook] SET SectionID=TT2.newsecidFROM [SmartCampus].[dbo].[R_ResAndBo ...
- jquery中ready函数,$(function(){})与自执行函数的区别
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 【转】H5+css布局+js+前端和移动端ui+其他汇总
无意间发现一个博客比较好,由于内容比较多,就把链接转过来,先保存着方便看的时候看. 感谢博主“张果” +++++++++++++++++++++++++++++++++++++++++++++++++ ...
- Elasticsearch前沿:ES 5.x改进详解与ES6展望
转:http://www.dataguru.cn/article-11094-1.html 曾勇(Medcl),Elastic 工程师与布道师,2015 年加入 Elastic 公司.加入 Elast ...
- 【poj1743】Musical Theme 【后缀自动机】
题意 给出一个n个数字的序列,找出相同变化趋势且不重叠的两个最长子串. 分析 这个题以前应该用后缀数组+二分做过.学了后缀自动机后可以用后缀自动机搞一下. 先差分,然后把查分后的数组建SAM.然后对于 ...
- 【2018沈阳赛区网络预选赛J题】Ka Chang【分块+DFS序+线段树】
题意 给出一个有根树(根是1),有n个结点.初始的时候每个结点的值都是0.下面有q个操作,操作有两种,操作1.将深度为L的点的值全部增加X.操作2.查询以x为根的子树的结点值得和. 其中N,Q< ...
- 关于java是值传递还是引用传递
一.概念 实际上对这两种传递方式,知乎上有个回答说得很好: 值传递和引用传递,属于函数调用时参数的求值策略(Evaluation Strategy),这是对调用函数时,求值和传值的方式的描述,而非传递 ...