【模板】树的直径(dfs & dp)
树的直径

给定n个点 n-1条边 和每条边的val
输出直径的大小和 直径上的点的序号
input:
8
1 2 2
1 3 1
1 5 10
2 4 3
4 6 4
3 7 5
7 8 2
output:
19
6 4 2 1 5
法1.DFS
思路:跑两遍dfs 第一次求出一个端点c1,第二次求出第二个端点c2
第一次:任意一个点跑一遍dfs 记录最远的点为c1 ,二次:这个时候dist[c1]=0 从c1开始跑dfs
缺点:不能处理存在val为负数的情况
#include <cstdio>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#define ep emplace_back
#define lld long long
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0);
#define vec vector
const int N = 2e5+9;
const int INF = 0x7FFFFFFF; //2147483647
const int inf1 = 0x3f3f3f3f; //1061109567
const int inf2 = 0x7f7f7f7f; //2139062143 memset赋值用
using namespace std;
int c1,c2;//直径的两个端点
int c;//处理c1,c2用
int n;
int head[N],idx=0;
int dist[N];
int prenodes[N];
struct node{
int to,val,next;
};
node e[N];
void add(int u,int v,int val){
e[idx] = {v,val,head[u]};
head[u] = idx++;
}
void bd(){
cin>>n;
memset(head,-1,sizeof head);
for(int i=1 ; i<=n-1 ; ++i){
int u,v,val;
cin>>u>>v>>val;
add(u,v,val);
add(v,u,val);
}
}
void dfs(int u,int fa,int tag){
//tag==1才记录路径
for(int i=head[u] ; i!=-1; i=e[i].next){
int v = e[i].to;
int val = e[i].val;
if(v == fa) continue;
dist[v] = dist[u] + val;
if(tag==1)
prenodes[v] = u;
if(dist[v] > dist[c])
c=v;
dfs(v,u,tag);
}
}
int main(){
ios;
bd();
dfs(1,0,0);
c1=c;
dist[c]=0;
dfs(c,0,1);
//记录第一个端点c1 = c 此时从c1开始 赋值dist[c1]=0;
c2=c;
cout<<dist[c]<<"\n";
for(int i=c2 ; i!=0 ;i=prenodes[i]) cout<<i<<" ";
return 0;
}
法2:树形的dp
#include <cstdio>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#define ep emplace_back
#define lld long long
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0);
#define vec vector
const int N = 2e5+9;
const int INF = 0x7FFFFFFF; //2147483647
const int inf1 = 0x3f3f3f3f; //1061109567
const int inf2 = 0x7f7f7f7f; //2139062143 memset赋值用
using namespace std;
int n, d = 0;
int dp[N];
vector<int> E[N];
void dfs(int u, int fa) {
for (int v : E[u]) {
if (v == fa) continue;
dfs(v, u);
d = max(d, dp[u] + dp[v] + 1);
dp[u] = max(dp[u], dp[v] + 1);
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n-1; i++) {
int u, v;
scanf("%d %d", &u, &v);
E[u].push_back(v);
E[v].push_back(u);
}
dfs(1, 0);
printf("%d\n", d);
return 0;
}
【模板】树的直径(dfs & dp)的更多相关文章
- 图论--树的直径--DFS+树形DP模板
#include <iostream> #include <cstring> using namespace std; //maxv:源点能到的最远点,maxdis:最远点对应 ...
- 【BZOJ-1912】patrol巡逻 树的直径 + DFS(树形DP)
1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1034 Solved: 562[Submit][St ...
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- 2014 Super Training #9 E Destroy --树的直径+树形DP
原题: ZOJ 3684 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3684 题意: 给你一棵树,树的根是树的中心(到其 ...
- Codeforces 592D - Super M - [树的直径][DFS]
Time limit 2000 ms Memory limit 262144 kB Source Codeforces Round #328 (Div. 2) Ari the monster is n ...
- [10.12模拟赛] 老大 (二分/树的直径/树形dp)
[10.12模拟赛] 老大 题目描述 因为 OB 今年拿下 4 块金牌,学校赞助扩建劳模办公室为劳模办公室群,为了体现 OI 的特色,办公室群被设计成了树形(n 个点 n − 1 条边的无向连通图), ...
- Codeforces 633F 树的直径/树形DP
题意:有两个小孩玩游戏,每个小孩可以选择一个起始点,并且下一个选择的点必须和自己选择的上一个点相邻,问两个选的点权和的最大值是多少? 思路:首先这个问题可以转化为求树上两不相交路径的点权和的最大值,对 ...
- HDU4514 湫湫系列故事——设计风景线 ——树的直径/树形dp+判环
中文题面,给出一个图,问能不能成环,如果可以就输出YES.否则输出该树的直径. 这里的判环我们用路径压缩的并查集就能很快的判断出来,可以在输入的同时进行判断.这题重点就是求树的直径. 树直径的性质可以 ...
- 历届试题 大臣的旅费-(树的直径+dfs)
问题描述 很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首 ...
- 【lightoj-1094】树的直径(DFS)
链接:http://www.lightoj.com/volume_showproblem.php?problem=1094 题意: 一共n各节点编号0-n-1, 输入n-1条无向边代表u-v距离为w, ...
随机推荐
- 搭建springboot redis项目
1.创建项目 如果出现init失败(需要等待网络可以正常连接) 或者运行主类的时候报错(错误: 找不到或无法加载主类),需要重新导入maven项目再重新编译试试. 2.引入pom jar <?x ...
- Oracle常用命令收藏
查看数据库名 SELECT t.NAME FROM V$DATABASE t; 查看实例名 SELECT t.INSTANCE_NAME FROM V$INSTANCE t; 查看SID select ...
- Linux查看系统占用
## 查看内存占用 #CPU占用最多的前10个进程: ps auxw|head -1;ps auxw|sort -rn -k3|head -10 #内存消耗最多的前10个进程 ps auxw|head ...
- Class 与 Style 如何动态绑定?
Class 可以通过对象语法和数组语法进行动态绑定: 对象语法: <div v-bind:class="{ active: isActive, 'text-danger': hasEr ...
- MongoDB安装、基础操作和聚合实例详解
虽然MongoDB这些年很流行,但笔者之前没研究过,现在有需求研究这类NoSQL的数据库,是为了验证其是否可被替换. MongoDB是很轻量的文档数据库,简单测试也懒得专门准备虚拟机环境了,直接在ma ...
- oeasy教您玩转vim - 27 - 文件类型
文件类型 回忆上节课内容 上次了解了缩进的各种方式 正常模式下用 << 缩进 插入模式下用 tab 缩进 显示缩进情况 :set listchars=eol:$,tab:>-,s ...
- JavaScript小面试~数组相关的方法和运用(学习笔记)
1,稀疏数组 稀疏数组是指数组中的某个下标未给出值或某个下标的值被删除.例如: let arrayOne=['xiaozi',,12,,true,23] let arrayTwo=[1,2,3,3,4 ...
- CF1950B Upscaling题解
CF1950B Upscaling题解 题意 给予你一个正整数 \(n\),构造一个如图的字符矩阵. 思路 注意数据 \(1\le n \le 20\),可以发现数据很小,于是我们可以暴力模拟. 我们 ...
- .NET跨平台UI框架Avalonia 11.1重磅发布
本篇为译文 原文地址 https://avaloniaui.net/blog/avalonia-11-1-a-quantum-leap-in-cross-platform-ui-development ...
- 单细胞测序最好的教程(十六):关于RNA速率你想知道的都在这
作者按 本章节详细讲解了基于RNA速率的三种拟时序模型,包括稳态模型,EM模型和深度学习模型,并对比了不同模型的适用场景与计算特点.本教程首发于单细胞最好的中文教程,未经授权许可,禁止转载. 全文字数 ...