再谈树---无根树转有根树( dfs搜索转化+fa数组记录父节点) *【模板】

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#define N 100000+2
using namespace std;

//无根树转有根树算法
/*
  算法分析:所谓无根树,就是根节点任意的树。我们可以给它确定一个根节点。
  我们可以假定认为某一个节点为根节点,然后从该节点开始进行dfs或者bfs搜索,
  在搜索的过程中,就像记录路径那样记录一个father[]数组,用来记录当前节点的
  父亲节点。算法很简单,需要注意两个地方:
  (*1.设置根节点father[root]=-1; 表示根节点没有父节点
  (*2.bfs或dfs的搜索过程中,判断遇到的点是不是根节点,不是的话就进行父节点的
  指定。如果是根节点的话,千万不要修改,如果忘记判断这个条件,将引起无限递归(dfs)
  或者无限循环(bfs)
*/
int n; //n个节点,n-1条边,vector创建二维数组存储(动态存储可以不用考虑存储大小)
vector<int>q[N];
int fa[N]; //记录父节点信息

void dfs(int u, int father)//递归转化以u为根节点,u的父节点为father
{
    int len=q[u].size(); //遍历与该点相连的点
    for(int i=0; i<len; i++)
    {
        int v=q[u][i]; //获取该点
        if(v!=father) //*判断v和其父节点是否相同,否则引起无限循环
            dfs(v, fa[v]=u); //把v的父节点设为u,然后递归转化以v根节点的子树
    }
}

int main()
{
    scanf("%d", &n);
    int u, v;
    for(int i=0; i<n-1; i++)
    {
        scanf("%d %d", &u, &v);
        q[u].push_back(v);
        q[v].push_back(u);
    }
    //进行dfs转化有根树
    fa[1]=-1;
    dfs(1, -1);

    return 0;
}
时间: 2024-10-03 22:41:58

再谈树---无根树转有根树( dfs搜索转化+fa数组记录父节点) *【模板】的相关文章

第11章 11.1再谈树

11.1.1:有根树转无根树 #include<iostream> #include<cstring> #include<vector> #include<cstdio> #define maxn 1000 using namespace std; vector<int> G[maxn]; int p[maxn]; void read_tree() { int n,u,v; scanf("%d",&n); for(in

poj 1330 【最近公共祖先问题+fa[]数组+ 节点层次搜索标记】

题目地址: 节点编号为:1-->n 代码: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <math.h> #include <iostream> #include <queue> #include <stack> #include <vector> #include

ACM:树的变换,无根树转有根树

题目: 输入一个n个节点的无根树的各条边,并指定一个根节点,要求把该树转化为有根树,输出各个节点的父亲编号. 分析:分析在代码的注释中! #include <iostream> #include <vector> using namespace std; const int MAXN = 1000; int n, p[MAXN]; vector<int> G[MAXN]; void dfs(int u, int fa) { //递归转化为以u为根的子树,u的父亲为fa

codeforces 570 D. Tree Requests 树状数组+dfs搜索序

链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Roman planted a tree consisting of n vertices. Each vertex contains a low

蒟蒻浅谈树链剖分之一——两个dfs操作

树链剖分,顾名思义就是将树形的结构剖分成链,我们以此便于在链上操作 首先我们需要明白在树链剖分中的一些概念 重儿子:某节点所有儿子中子树最多的儿子 重链:有重儿子构成的链 dfs序:按重儿子优先遍历时的顺序 轻儿子的意思就与重儿子相反 首先是第一个dfs操作 在本次操作中,我们主要做的是处理所有节点的父亲,子树大小,重儿子,深度等操作 void dfs1(int now,int father,int deep) { tree[now].depth=deep;//初始化当前节点的深度,子树大小,父

大臣的旅费---树的直径(dfs)

很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达. 同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的. J是T国重要大臣,他巡查于各大城市之间,体察民情. 所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情.他有一个钱袋,用于存放往来城市间的路费. 聪明的J发现,如果不在某个城市停下来修整,在连续行进过

浅谈树的重心

浅谈树的直径 定义: 树上一节点最大子树的节点数最小: 性质: 1.删除重心后所得的所有子树,节点数不超过原树的1/2,一棵树最多有两个重心: 2.树中所有节点到重心的距离之和最小,如果有两个重心,那么他们距离之和相等: 3.两个树通过一条边合并,新的重心在原树两个重心的路径上: 4.树删除或添加一个叶子节点,重心最多只移动一条边: 求解: 求解方法多种多样,分别用到不同的定义和性质: 1.定义求解: siz [ i ]表示 i 节点的子树大小 dp [ i ]表示以 i 为根节点的最大子树大小

C++ Primer 学习笔记_73_面向对象编程 --再谈文本查询示例

面向对象编程 --再谈文本查询示例 引言: 扩展第10.6节的文本查询应用程序,使我们的系统可以支持更复杂的查询. 为了说明问题,将用下面的简单小说来运行查询: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he

URAL 1298 knight dfs搜索

1298. Knight Time limit: 2.0 second Memory limit: 64 MB Even paratroopers have vacations. The flight to Sirius in the depths of "The Admiral Brisco" Leo Hao whiled away with chessboard. No, he did not like usual chess game, and in addition, he d