ALDS1_11_B:Depth First Search

时间:2021-12-20 21:33:58

邻接表的方式给一个图,输出对这个图进行dfs之后,每个节点的开始搜索和结束搜索时间。

题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_11_B

首先,如果我想做对一个邻接矩阵的深度优先遍历,dfs
我需要用一个栈来存储,我需要访问的元素。

首先把第一个节点放进去,然后按照顺序遍历一遍节点表,如果有边能通向一个还没有访问过的节点,那么就把这个节点放进去;直到,最后放进去的这个节点,它所有的边通向的节点,都访问过了,那么就开始pop出来一个元素,然后搜索最顶端的元素,是不是还有其他相邻节点没有被访问过,如果有,就push进栈里。。重复这个操作,知道都访问过。

但是由于,在转换为邻接矩阵的时候,只保留了一半路径,可能会出现,有的节点访问不到的情况,所以加上修正。这种情况的测试数据如下:

6
1 2 2 4
2 1 5
3 2 5 6
4 0
5 1 4
6 1 6
-----output-----
1 1 8
2 2 7
3 0 0
4 4 5
5 3 6
6 0 0

整体代码如下:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstring>
using namespace std;

bool A[110][110],flag[110];
int in[110],out[110];
int n,now=1;
stack<int> S;

void dfs_visit(int u){
	flag[u]=true;
	for(int i=1;i<=n;i++){
		if(A[u][i]==true && flag[i]==false) {
			S.push(i);
			in[i]=now++;
			dfs_visit(i);
		}
	}
	int x=S.top();
	S.pop();
	out[x]=now++;
	return ;
}

void dfs(){
	S.push(1);in[1]=now++;
L1:	while(S.empty()==0){
		int x=S.top();
		dfs_visit(x);
	}
	for(int i=1;i<=n;i++){
		if(flag[i]==false){
			S.push(i);in[i]=now++;goto L1;
		}
	}
	for(int i=1;i<=n;i++) cout<<i<<" "<<in[i]<<" "<<out[i]<<endl;
	return ;
}

int main (){
	int a,b,c;
	cin>>n;
	for(int i=1;i<=n;i++){
		flag[i]=false;
			for(int j=1;j<=n;j++){
				A[i][j]=false;
		}
	}
	for(int i=1;i<=n;i++){
		cin>>a>>b;
		for(int j=1;j<=b;j++){
			cin>>c;
			A[a][c]=true;
		}
	}
	dfs();
	return 0;

}

错点:

1.考虑到存储的问题,加上修正。

	for(int i=1;i<=n;i++){
		if(flag[i]==false){
			S.push(i);in[i]=now++;goto L1;
		}
	}

2.注意初始化

3.注意第一次push(1)进去的时候,要对1的intime自己写。

也可以用递归的方式完成,代码如下:

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

bool A[110][110];
int flag[110],in[110],out[110];
int now=1,n;

void dfs(int u){
	flag[u]=1;
	in[u]=now++;
	for(int i=1;i<=n;i++){
		if(flag[i]==0 && A[u][i]==true){
			dfs(i);
		}
	}
	out[u]=now++;
	return ;
}

int main(){
	int a,b,c;
	cin>>n;
	for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				A[i][j]=false;
		}
	}
	for(int i=1;i<=n;i++){
		cin>>a>>b;
		for(int j=1;j<=b;j++){
			cin>>c;
			A[a][c]=true;
		}
	}
	for(int i=1;i<=n;i++){
		if(flag[i]==0) dfs(i);
	}
	for(int i=1;i<=n;i++){
		cout<<i<<" "<<in[i]<<" "<<out[i]<<endl;
	}
	return 0;
}

错点:

1.注意in和out time赋值的时间。