@[TOC]
欧拉序与DFS序相似又不同

欧拉序的定义
树在dfs过程中的节点访问顺序称为欧拉序.
那有人会问:dfs序和欧拉序啥区别?

dfs序:是指将一棵树被dfs时所经过的节点顺序(不绕回原点)。
欧拉序:就是从根结点出发,按dfs的顺序在绕回原点所经过所有点的顺序。

在这里插入图片描述
欧拉序与dfs序不同地方在于,欧拉序中每个节点可以出现多次,比如进入一次退出一次,又比如每次回溯时记录一次。
代码:

s[maxn]存放“入时间戳”,e[maxn]存放“出时间戳”;

DFS序

核心代码

const int maxn = 1e5+5;
vector<int> g[maxn]; //存放节点
int s[maxn], e[maxn];//s[maxn]存放“入时间戳”,e[maxn]存放“出时间戳”;
int n,id,len;
int dfsxu[20000];//存放dfs序

void dfs(int u, int fa) {
    s[u] = ++id;
    dfsxu[++len]=u;
    for(int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i];
        if(v == fa) continue;
        dfs(v, u);
    }
    e[u] = id;
}

vector<int> g[maxn]; //存放节点
int s[maxn], e[maxn];//s[maxn]存放“入时间戳”,e[maxn]存放“出时间戳”;
int dfsxu[20000];//存放dfs序
完整代码</int>

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
vector<int> g[maxn]; //存放节点
int s[maxn], e[maxn];//s[maxn]存放“入时间戳”,e[maxn]存放“出时间戳”;
int n,id,len;
int dfsxu[20000];//存放dfs序

void dfs(int u, int fa) {
    s[u] = ++id;
    dfsxu[++len]=u;
    for(int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i];
        if(v == fa) continue;
        dfs(v, u);
    }
    e[u] = id;
}
int main() {
    memset(s,0,sizeof(s));
    memset(e,0,sizeof(e));
    memset(dfsxu,0,sizeof(dfsxu));
    ios::sync_with_stdio(0);
    cin >> n;
    for(int i = 1; i < n; ++i) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    id = 0;
    dfs(1, -1);
    cout<<"DFS序:";
    for(int i=1;s[i]!=0;i++)
    {
        cout<<dfsxu[i];
    }
    cout<<endl;
    cout<<"入时间戳:";
    for(int i=1;s[i]!=0;i++)
    {
        cout<<s[i];
    }
    cout<<endl;
    cout<<"出时间戳:";
    for(int i=1;e[i]!=0;i++)
    {
        cout<<e[i];
    }
    cout<<endl;

    return 0;
}

欧拉序

vector<int> g[40010]; //存放节点
int oulaxu[80020]; //存放欧拉序在,在欧拉序中第一次出现为“入时间戳”,第二次出现为“出时间戳”。
核心代码</int>

vector<int> g[40010]; //存放节点
int oulaxu[80020]; //存放欧拉序在,在欧拉序中第一次出现为“入时间戳”,第二次出现为“出时间戳”。
int len;

void dfs(int u,int fa)
{
    oulaxu[++len]=u;
    int sz=g[u].size();
    for(int i=0; i<sz; i++)
    {
        if(g[u][i]!=fa)
            dfs(g[u][i],u);
        }

    oulaxu[++len]=u;
}

vector<int> g[40010]; //存放节点
int oulaxu[80020]; //存放欧拉序在,在欧拉序中第一次出现为“入时间戳”,第二次出现为“出时间戳”。
完整代码</int>

#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

vector<int> g[40010]; //存放节点
int oulaxu[80020]; //存放欧拉序在,在欧拉序中第一次出现为“入时间戳”,第二次出现为“出时间戳”。
int len;

void dfs(int u,int fa)
{
    oulaxu[++len]=u;
    int sz=g[u].size();
    for(int i=0; i<sz; i++)
    {
        if(g[u][i]!=fa)
            dfs(g[u][i],u);
        }

    oulaxu[++len]=u;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        len=0;
        memset(oulaxu,0,sizeof(oulaxu));
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            g[i].clear();
        }
        for(int i=1; i<=n-1; i++)
        {
            int from,to;
            scanf("%d%d",&from,&to);
            g[from].push_back(to);
            g[to].push_back(from);
        }
        dfs(1,0);
        for(int i=1;i<=len;i++)
        {
            printf("%d ",oulaxu[i]);
        }
    }

}