ALDS1_11_B:Depth First Search

 


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

 

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

首先,如果我想做对一个邻接矩阵的深度优先遍历,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赋值的时间。

 

----------------8th June update------------------

 

 直接用栈来实现dfs的实现中,可以把“先把1节点push进栈”这个操作放到后面的修正步骤中,来避免使用goto。

同时,dfs函数可以直接放到main函数里面,直接用dfs_visit来递归调用dfs

整体代码如下:

 

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

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;
		}
	}
	for(int i=1;i<=n;i++){
		if(flag[i]==false){
			S.push(i);in[i]=now++;
			while(S.empty()==0){
					int x=S.top();
					dfs_visit(x);
				}
		}
	}
	for(int i=1;i<=n;i++) cout<<i<<" "<<in[i]<<" "<<out[i]<<endl;
	return 0;

}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值