邻接表的方式给一个图,输出对这个图进行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赋值的时间。