IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 树、存储DFS/BFS序、树的直径 -> 正文阅读

[数据结构与算法]树、存储DFS/BFS序、树的直径

存储

链式前向星或者vector<edge>。图和树的存储方法一致。

有根树的DFS/BFS序

遍历一棵树的方法有两种:DFS/BFS。DFS是一直往深处走,在搜索过程中依次记录经过的点所生成的序列就是DFS序。DFS序不唯一。

DFN的求法:

#define pb push_back
std::vector<int> dfn; // dfn中的元素即为dfs序
std::vector<int> tree[maxn];
void dfs(int x) {
    dfn.pb(x);
    for(auto son:tree[x]) {
        dfs(son);
    }
}
int main(){
    int root=1; // 具体情况而定
    dfs(root);
}

有根树的BFS是按照层级顺序搜索,按照深度从小到大依次遍历所有的点。队列里元素出现的顺序就是BFS序。

BFS序求法:

#define pb push_back
std::vector<int> tree[maxn];
queue<int> q;
void bfs(int x) {
    q.push(x);
    while (!q.empty()) {
        int y=q.front();
        q.pop();
        for(auto son:tree[y]) {
            q.push(son);
        }
    }
}
int main(){
    int root=1; // 具体情况而定
    bfs(root);
}

无根树的DFS/BFS序

无根树中的节点只有相邻关系而没有父子关系。

遍历无根树时,可以从任意节点出发,像遍历有根树一样遍历整颗树。区别是要记录此节点的来源,以免无限递归再次访问。

树的直径

树上任意两个节点之间最长的距离(经过的边的数目)。路径不是唯一的。

树的直径的中间节点被称为树的中心,如果直径上有偶数个节点,那么中间两个点都是树的中心。**树的中心到其他点的最长路径最短。**树的中心是唯一确定的。

求直径的方法:从任意节点开始搜索距离其最远的点a,然后从a点开始重新搜索距离其最远的点b,则路径a-b即为树的直径之一。

例题

给你一棵树,让你求出这棵树的直径长度(直径经过的边的数量)。

树以下列方式给出:

  • 输入第一行给出一个数 nn,表示一共有 nn 个节点;
  • 接下来 n?1n?1 行,每行给出两个数 x,y(x≠y)x,y(x≠y),表示 x,yx,y 之间有一条边。

输入格式

见题面。

输出格式

输出一个数,表示答案。

样例输入

4
1 2
1 3
3 4

样例输出

3

数据规模

对于所有数据,保证1≤n≤100000,1≤x,y≤n,x≠y1≤n≤100000,1≤x,y≤n,x≠y。

代码

一开始写的是链式前向星,结果超时了。后来换成vector就好了。

#include <bits/stdc++.h>
typedef long long ll;
#define pb push_back
#define pob pop_back
#define mem(a,b) memset(a,b,sizeof(a))
#define all(a) (a).begin(),(a).end()
#define debug(a) cout<<#a<<"="<<a<<endl;
inline ll rr(){ll f=1,x=0;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');return f*x;}
using namespace std;
const ll INF=0x3f3f3f3f,inf=0x3f3f3f3f3f3f3f;
const int maxn=1e5+6;

int n,cnt;
int head[maxn],nxt[maxn],to[maxn];
int pre[maxn],dis[maxn];
std::vector<int> edge[maxn];
void add_edge(int u,int v) {
    nxt[++cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v;
}
void init() {
    n=rr();
    for(int i=1;i<n;i++) {
        int u=rr(),v=rr();
        edge[u].pb(v);
        edge[v].pb(u);
    }
}
void dfs(int u) {
    for(auto v:edge[u]) {
        if(v!=pre[u]) { // 不是其父
            pre[v]=u;
            dis[v]=dis[u]+1;
            dfs(v);
        }
    }
}
int main(){
    init();
    int minv=-1,idx=1;
    dfs(1);
    for(int i=1;i<=n;i++) {
        if(minv<dis[i]) {
            minv=dis[i];
            idx=i;
        }
    }
    for(int i=1;i<=n;i++) pre[i]=dis[i]=0;
    dfs(idx);
    minv=-1,idx=1;
    for(int i=1;i<=n;i++) {
        if(minv<dis[i]) minv=dis[i];
    }
    std::cout << minv << '\n';
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:48:40  更:2022-07-17 16:54:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:14:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码