定义 :在一棵树中,每一个节点在dfs深度优先遍历的时间序列(将树形结构转化为线性结构)
核心代码及数据结构
vector<int> tree[100]; //存放的栈,为什么不用数组?因为栈好处理
int in[100]; //进入的时间戳
int out[100]; //出去的时间戳
int num[200]; //存放树dfs序列||树的前序遍历
int t = 0; //记录序列的时间
void dfs(int x, int fa) {
in[x] = ++t; //进入的时间戳
num[t] = x; //生成新的线性结构
for(int i = 0; i < tree[x].size(); i++) {
int cnt = tree[x][i];
if(cnt == fa) continue;
dfs(cnt, x);
}
out[x] = t; //出去的时间戳
}
题目:求树中以某点为根节点的子树
代码
#include <bits/stdc++.h>
using namespace std;
vector<int> tree[100]; //存放的栈,为什么不用数组?因为栈好处理
int in[100]; //进入的时间戳
int out[100]; //出去的时间戳
int num[200]; //存放树dfs序列||树的前序遍历
int t = 0; //记录序列的时间
void dfs(int x, int fa) {
in[x] = ++t; //进入的时间戳
num[t] = x; //生成新的线性结构
for(int i = 0; i < tree[x].size(); i++) {
int cnt = tree[x][i];
if(cnt == fa) continue;
dfs(cnt, x);
}
out[x] = t; //出去的时间戳
}
int main()
{
int n; //n表示多少结点
int u, v;
int r,op; //r表示以某点作为子树的根节点,op表示询问多少次数
while(scanf("%d %d", &n,&op) != EOF)
{
for(int i = 0; i < n-1; i++)
{
scanf("%d %d", &u, &v);
tree[u].push_back(v);
tree[v].push_back(u);
}
dfs(1, -1);
//显示数组
/*
for(int i=1;in[i]!=0;i++)
{
cout<<in[i];
}
cout<<endl;
for(int i=1;out[i]!=0;i++)
{
cout<<out[i];
}
cout<<endl;
for(int i=1;num[i]!=0;i++)
{
cout<<num[i];
}
cout<<endl;
*/
while(op--)
{
cin>>r;
for(int i=in[r];i<=out[r];i++)
{
cout<<num[i];
}
cout<<endl;
}
}
return 0;
}
运行结果
题目:
有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个操作,分为三种:
操作 1 :把某个节点 r 的点权增加 s 。
操作 2 :把某个节点 r 为根的子树中所有点的点权都增加 s 。
操作 3 :查询以第r节点为根节点的子树
操作4:查询以第r节点为根节点的子树节点和
代码
#include <bits/stdc++.h>
using namespace std;
vector<int> tree[100]; //存放的栈,为什么不用数组?因为栈好处理
int in[100]; //进入的时间戳
int out[100]; //出去的时间戳
int num[200]; //存放树dfs序列||树的前序遍历
int t = 0; //记录序列的时间
void dfs(int x, int fa) {
in[x] = ++t; //进入的时间戳
num[t] = x; //生成新的线性结构
for(int i = 0; i < tree[x].size(); i++) {
int cnt = tree[x][i];
if(cnt == fa) continue;
dfs(cnt, x);
}
out[x] = t; //出去的时间戳
}
int main()
{
int n,m; //n表示多少结点
int u, v;
int r,op,s; //r表示以某点作为子树的根节点,op表示询问多少次数
while(scanf("%d %d", &n,&m) != EOF)
{
for(int i = 0; i < n-1; i++)
{
scanf("%d %d", &u, &v);
tree[u].push_back(v);
tree[v].push_back(u);
}
dfs(1, -1);
//显示数组
/*
cout<<"第i节点子树的入栈时间:";
for(int i=1;in[i]!=0;i++)
{
cout<<in[i];
}
cout<<endl;
cout<<"第i节点子树的出栈时间:";
for(int i=1;out[i]!=0;i++)
{
cout<<out[i];
}
cout<<endl;
cout<<"DFS序列(前序遍历) :";
for(int i=1;num[i]!=0;i++)
{
cout<<num[i];
}
cout<<endl;
*/
while(m--)
{
cin>>op;
if(op==1) //op==1时,以第r节点加s
{
cin>>r>>s;
num[r] = num[r]+s;
}
if(op==2) //op==2时,以第r节点为根节点的子树节点加s
{
cin>>r>>s;
for(int i=in[r];i<=out[r];i++)
{
num[i]= num[i]+s;
}
}
if(op==3) //op==3时,查询以第r节点为根节点的子树
{
cin>>r;
for(int i=in[r];i<=out[r];i++)
{
cout<<num[i];
}
cout<<endl;
}
if(op==4) //op==4时,查询以第r节点为根节点的子树的节点和
{
cin>>r;
int sum=0;
for(int i=in[r];i<=out[r];i++)
{
sum= sum+num[i];
}
cout<<sum<<endl;
}
}
}
return 0;
}