对于给定的一棵树,其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。

Solution

有点意思

先随便求一条直径(两次DFS即可),不妨设为 \(s,t\),我们知道要求的这些边一定都在这条路径上,不妨将它看作一条线(用DFS + STACK把它提取出来),其中 \(s\) 叫左边, \(t\) 叫右边

我们现在就要在这条线上借出一段区间

考虑如何求它的右端点,以 \(s\) 为根跑 DFS,算出每个点子树的最长路径以及条数

从 \(t\) 往左扫,如果碰到某条边不是必须经过的边(可以根据 \(u,v\) 的最长路条数关系判断),就把它记下来

那么最后一次被记下来的边的左端点就是目标区间的右端点

左端点同理即可

#include <bits/stdc++.h>
using namespace std; #define int long long
const int N = 200005; vector <pair<int,int> > g[N];
int n,x[N],y[N],top; namespace sol1 {
int vis[N],dis[N],s,t,len;
void dfs(int p) {
vis[p]=1;
for(int i=0;i<g[p].size();i++) {
int q=g[p][i].first, w=g[p][i].second;
if(vis[q]==0) {
dis[q]=dis[p]+w;
dfs(q);
}
}
}
void solve() {
int tmp=0;
dfs(1);
for(int i=1;i<=n;i++) {
if(dis[tmp]<dis[i]) tmp=i;
}
s=tmp;
memset(vis,0,sizeof vis);
memset(dis,0,sizeof dis);
dfs(s);
for(int i=1;i<=n;i++) {
if(dis[tmp]<dis[i]) tmp=i;
}
t=tmp;
len=dis[tmp];
}
} namespace sol2 {
int vis[N],s,t;
bool dfs(int p) {
vis[p]=1;
if(p==s) return 1;
for(int i=0;i<g[p].size();i++) {
int q=g[p][i].first, w=g[p][i].second;
if(vis[q]==0) {
int tmp = dfs(q);
if(tmp) {
x[++top]=q;
y[top]=w;
return 1;
}
}
}
}
void solve(int _s,int _t ){
s=_s; t=_t;
dfs(t);
x[++top]=t;
}
} namespace sol3 {
int vis[N],f[N],h[N];
void dfs(int p) {
vis[p]=1;
h[p]=1;
for(int i=0;i<g[p].size();i++) {
int q=g[p][i].first, w=g[p][i].second;
if(vis[q]==0) {
dfs(q);
if(f[p]<f[q]+w) {
f[p]=f[q]+w;
h[p]=0;
}
if(f[p]==f[q]+w) h[p]+=h[q];
}
}
}
int solve(int s) {
dfs(s);
int ans=top;
//for(int i=1;i<=top;i++) cout<<h[x[i]]<<" ";
//cout<<endl;
for(int i=top-1;i;--i) {
if(h[x[i]]!=h[x[i+1]]) ans=i;
}
return ans;
}
} namespace sol4 {
int vis[N],f[N],h[N];
void dfs(int p) {
vis[p]=1;
h[p]=1;
for(int i=0;i<g[p].size();i++) {
int q=g[p][i].first, w=g[p][i].second;
if(vis[q]==0) {
dfs(q);
if(f[p]<f[q]+w) {
f[p]=f[q]+w;
h[p]=0;
}
if(f[p]==f[q]+w) h[p]+=h[q];
}
}
}
int solve(int s) {
dfs(s);
int ans=1;
//for(int i=1;i<=top;i++) cout<<h[x[i]]<<" ";
//cout<<endl;
for(int i=2;i<=top;i++) {
if(h[x[i]]!=h[x[i-1]]) ans=i;
}
return ans;
}
} signed main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<n;i++) {
int t1,t2,t3;
cin>>t1>>t2>>t3;
g[t1].push_back(make_pair(t2,t3));
g[t2].push_back(make_pair(t1,t3));
}
sol1::solve();
int s=sol1::s, t=sol1::t;
sol2::solve(s,t);
int ans1=sol3::solve(s);
int ans2=sol4::solve(t);
cout<<sol1::len<<endl<<ans1-ans2<<endl;
}

[SDOI2013] 直径 - 树形dp的更多相关文章

  1. bzoj3124: [Sdoi2013]直径 树形dp two points

    题目链接 bzoj3124: [Sdoi2013]直径 题解 发现所有直径都经过的边 一定在一条直径上,并且是连续的 在一条直径上找这段区间的两个就好了 代码 #include<map> ...

  2. 【BZOJ3124】[Sdoi2013]直径 树形DP(不用结论)

    [BZOJ3124][Sdoi2013]直径 Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节 ...

  3. BZOJ3124: [Sdoi2013]直径 (树形DP)

    题意:给一颗树 第一问求直径 第二问求有多少条边是所有直径都含有的 题解:求直径就不说了 解第二问需要自己摸索出一些性质 任意记录一条直径后 跑这条直径的每一个点  如果以这个点不经过直径能到达最远的 ...

  4. 2014 Super Training #9 E Destroy --树的直径+树形DP

    原题: ZOJ 3684 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3684 题意: 给你一棵树,树的根是树的中心(到其 ...

  5. 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分

    树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...

  6. [10.12模拟赛] 老大 (二分/树的直径/树形dp)

    [10.12模拟赛] 老大 题目描述 因为 OB 今年拿下 4 块金牌,学校赞助扩建劳模办公室为劳模办公室群,为了体现 OI 的特色,办公室群被设计成了树形(n 个点 n − 1 条边的无向连通图), ...

  7. Codeforces 633F 树的直径/树形DP

    题意:有两个小孩玩游戏,每个小孩可以选择一个起始点,并且下一个选择的点必须和自己选择的上一个点相邻,问两个选的点权和的最大值是多少? 思路:首先这个问题可以转化为求树上两不相交路径的点权和的最大值,对 ...

  8. HDU4514 湫湫系列故事——设计风景线 ——树的直径/树形dp+判环

    中文题面,给出一个图,问能不能成环,如果可以就输出YES.否则输出该树的直径. 这里的判环我们用路径压缩的并查集就能很快的判断出来,可以在输入的同时进行判断.这题重点就是求树的直径. 树直径的性质可以 ...

  9. 51nod"省选"模测 A 树的双直径(树形dp)

    题意 题目链接 Sol 比赛结束后才调出来..不多说啥了,就是因为自己菜. 裸的up-down dp,维护一下一个点上下的直径就行,一开始还想了个假的思路写了半天.. 转移都在代码注释里 毒瘤题目卡空 ...

随机推荐

  1. 【Go语言系列】2.3、Go语言基本程序结构:变量及常量

    1.什么变量 变量来源于数学,从根本上说,变量相当于是对一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块存储空间. 1.1变量声明 Go 语言变 ...

  2. Android中使用画笔和画布绘制一个矩形

    场景 在Android中画笔使用Paint类,画布使用Canvas类来表示. 绘图的基本步骤 首先编写一个继承自View的自定义View类,然后重写其onDraw方法,最后把自定义的view添加到ac ...

  3. opencv中的图像矩(空间矩,中心矩,归一化中心矩,Hu矩)

    严格来讲矩是概率与统计中的一个概念,是随机变量的一种数字特征.设 x 为随机变量,C为常数,则量E[(x−c)^k]称为X关于C点的k阶矩.比较重要的两种情况如下: 1.c=0,这时a_k=E(X^k ...

  4. ajax 携带参数传递 页面 查找

    不从新定义只能传过来数字  ,不能穿字符串 完整的ajax 获取参数跳转页面

  5. SpringBoot 教程之 banner 定制

    目录   简介  变量  配置  编程  示例  参考资料 简介 Spring Boot 启动时默认会显示以下 LOGO: . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ ...

  6. 浅谈python的第三方库——numpy(一)

    python作为广受欢迎的一门编程语言,其中很重要的一个原因便是它可以使用很多第三方库. 对第三方库的理解,在笔者看来就是一些python爱好者和专门的研发机构,为满足某一特定应用领域的需要,使用py ...

  7. poj 2528 线段树区间修改+离散化

    Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...

  8. Apache Solr Velocity模板注入rce+获取交互式shell

    前言: 官方的poc.exp payload只能获取很低的命令执行权限,甚至有些符号.命令还被过滤了,例如管道符被过滤.并且不能写入.下载文件,不能使用管道符重定向文件.那么我们只能通过获取到交互式s ...

  9. Nginx配置HTTPS并将HTTP请求重定向到HTTPS

    个人博客 地址:https://www.wenhaofan.com/a/20190702214652 在阿里云获取免费的HTTPS证书 配置HTTPS之前首先需要拥有HTTPS证书,在阿里云可以获得域 ...

  10. 神经网络反向传播算法&&卷积神经网络

    听一遍课程之后,我并不太明白这个算法的奇妙之处?? 为啥? 神经网络反向传播算法 神经网络的训练依靠反向传播算法,最开始输入层输入特征向量,网络层计算获得输出,输出层发现输出和正确的类号不一样,这时就 ...