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 ...
随机推荐
- ios编译出错:UIButton.h' has been modified since the precompiled header UIKit.pcm' was built
今天编译遇到个问题:如下 fatal error: file '/Applications/Xcode 2.app/Contents/Developer/Platforms/iPhoneSimulat ...
- Spring <context:annotation-config />讲解
在基于主机方式配置Spring的配置文件中,你可能会见到<context:annotation-config />这样一条配置,他的作用是向Spring容器注册AutowiredAnnot ...
- Nginx源码完全注释(6)core/murmurhash
下面是摘自 Google Code 的 Murmurhash 开源项目主页上的 Murmurhash2,Nginx 就是采用的这个. uint32_t MurmurHash2 ( const void ...
- 148. Sort List (List)
Sort a linked list in O(n log n) time using constant space complexity. 法I:快排.快排的难点在于切分序列.从头扫描,碰到> ...
- 仿微信-ActionSheet
有时候我们在开发中,系统提供的actionsheet 不能满足我们的需求,所以,今天就做一个类似微信中的,支持多个按钮,我见有的人用的是个tableview,也可以,但是有点麻烦. 效果图: Acti ...
- android-tip-关于SurfaceView的使用
1. SurfaceView的创建和销毁 当SurfaceView隐藏时,SurfaceView被销毁,此时会调用SurfaceHolder.Callback.surfaceDestroyed ...
- Opencv Canny
#include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...
- 746. Min Cost Climbing Stairs 最不费力的加权爬楼梯
[抄题]: On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once yo ...
- linux系统文件属性详解
一.文件信息 当创建一个文件的时候,系统保存了有关该文件的全部信息,包括: 文件的位置: 文件类型: 文件长度: 哪位用户拥有该文件,哪些用户可以访问该文件: 硬连接计数: 文件的修改时间: 文件的权 ...
- Java 依赖注入标准(JSR-330)简介
作者:88250 ,Vanessa 时间:2009 年 11 月 19 日 Java 依赖注入标准(JSR-330,Dependency Injection for Java)1.0 规范已 ...