jdoj2781 DFS序列

题目描述

Description

给定一棵以1为根的有根树,输出这棵树的DFS序
要求在输入中后出现的边优先遍历

Input

第一行一个整数n,代表这棵树的节点数
接下来n-1行每行两个整数x和y,代表这两个节点间有一条边

Output

输出n行,为这棵树的DFS序

Sample Input

5
3 1
1 2
2 4
2 5

 Sample Output

1
2
5
4
3

HINT

n<=106

题目分析:

递归DFS爆栈 所以我们要用非递归
对于后出现的边先遍历 我们就用链式前向星存储边
利用栈:

  • 输出起始顶点,起始顶点改为“已访问”标志,将起始顶点进栈
  • 取栈顶元素顶点
  • 若存在栈顶元素顶点存在未被访问过的邻接点x,则:输出邻接点x,将邻接点x改为“已访问”标志,将邻接点x进栈
  • 否则,当前顶点出栈
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1210000];
int head[1100000],next[2100000],to[2100000];
bool visit[1001000];
int tot;
int n;
void add(int x,int y)
{
    ++tot;
    next[tot]=head[x];
    to[tot]=y;
    head[x]=tot;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    a[++a[0]]=1;
    visit[1]=true;
    printf("1\n");
    while(1)
    {
        int tmp=a[a[0]];
        bool flag=false;
        for(int i=head[tmp];i;i=next[i])
            if(!visit[to[i]])
            {
                a[++a[0]]=to[i];
                visit[to[i]]=true;
                printf("%d\n",to[i]);
                flag=true;
                break;
            }
        if(!flag) a[0]--;
        if(a[0]==0)break;
    }
}

发表评论

邮箱地址不会被公开。 必填项已用*标注