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;
}
}