为什么使用堆栈的 dfs 没有给出正确的结果
Why dfs using stack is not giving correct result
See DFS image Here
我正在使用堆栈打印 dfs 序列。根据输入和图形的图像,序列为 1 2 4 8 5 6 3 7 。但是我的代码给出的输出为 1 2 4 8 7 6 5 3 。谁能解释我该如何解决?
Input:
8 10
1 3
1 2
2 5
2 4
3 7
3 6
4 8
5 8
6 8
7 8
Correct Output:
Sequence: 1 2 4 8 5 6 3 7
我的代码:
#include <bits/stdc++.h>
using namespace std;
vector<int>edges[100];
stack<int>q;
vector<int>item;
int level[100],parent[100],visited[100],tn;
void dfs(int s)
{
int j,k,fr;
q.push(s);
level[s]=0;
for(j=1;j<=tn;j++)
{
visited[j]=0;
}
visited[s]=1;
while(!q.empty())
{
fr=q.top();
q.pop();
item.push_back(fr);
for(k=0;k<edges[fr].size();k++)
{
if(visited[edges[fr][k]]==0)
{
q.push(edges[fr][k]);
//cout<<"Pushed="<<fr<<"="<<edges[fr][k];
visited[edges[fr][k]]=1;
}
}
//cout<<endl;
}
}
int main()
{
int i,e,p,n,u,v,f,m;
cin>>tn>>e;
for(i=1;i<=e;i++)
{
cin>>u>>v;
edges[u].push_back(v);
edges[v].push_back(u);
}
dfs(1);
cout<<"Sequence="<<endl;
for(m=0;m<item.size();m++)
{
cout<<item[m];
}
return 0;
}
我的代码显示了这个输出:1 2 4 8 7 6 5 3
在实现中将节点标记为已访问包含错误;该函数可以重写如下。
void dfs(int s)
{
int j, k, fr;
q.push(s);
level[s] = 0;
for (j = 1; j <= tn; j++)
{
visited[j] = 0;
}
while (!q.empty())
{
fr = q.top();
q.pop();
if (0 == visited[fr])
{
visited[fr] = 1;
item.push_back(fr);
for (k = 0; k < edges[fr].size(); k++)
{
q.push(edges[fr][k]);
}
}
}
}
在这个版本中,节点只有在从堆栈中取出时才会被标记。请注意,检查节点是否已被访问是必要的,因为堆栈上的节点可能会被稍后的迭代访问。此实现产生序列
1 2 4 8 7 3 6 5
然而,这并不是描述为所需的解决方案。但是,请注意,如果没有额外的打破平局规则,DFS 算法允许访问顺序中存在一些歧义。顺序
1 2 4 8 5 6 3 7
可以通过将具有最小 id 的邻居最后压入堆栈来生成,从而在下一次迭代中访问它。
See DFS image Here
我正在使用堆栈打印 dfs 序列。根据输入和图形的图像,序列为 1 2 4 8 5 6 3 7 。但是我的代码给出的输出为 1 2 4 8 7 6 5 3 。谁能解释我该如何解决?
Input: 8 10 1 3 1 2 2 5 2 4 3 7 3 6 4 8 5 8 6 8 7 8 Correct Output: Sequence: 1 2 4 8 5 6 3 7
我的代码:
#include <bits/stdc++.h>
using namespace std;
vector<int>edges[100];
stack<int>q;
vector<int>item;
int level[100],parent[100],visited[100],tn;
void dfs(int s)
{
int j,k,fr;
q.push(s);
level[s]=0;
for(j=1;j<=tn;j++)
{
visited[j]=0;
}
visited[s]=1;
while(!q.empty())
{
fr=q.top();
q.pop();
item.push_back(fr);
for(k=0;k<edges[fr].size();k++)
{
if(visited[edges[fr][k]]==0)
{
q.push(edges[fr][k]);
//cout<<"Pushed="<<fr<<"="<<edges[fr][k];
visited[edges[fr][k]]=1;
}
}
//cout<<endl;
}
}
int main()
{
int i,e,p,n,u,v,f,m;
cin>>tn>>e;
for(i=1;i<=e;i++)
{
cin>>u>>v;
edges[u].push_back(v);
edges[v].push_back(u);
}
dfs(1);
cout<<"Sequence="<<endl;
for(m=0;m<item.size();m++)
{
cout<<item[m];
}
return 0;
}
我的代码显示了这个输出:1 2 4 8 7 6 5 3
在实现中将节点标记为已访问包含错误;该函数可以重写如下。
void dfs(int s)
{
int j, k, fr;
q.push(s);
level[s] = 0;
for (j = 1; j <= tn; j++)
{
visited[j] = 0;
}
while (!q.empty())
{
fr = q.top();
q.pop();
if (0 == visited[fr])
{
visited[fr] = 1;
item.push_back(fr);
for (k = 0; k < edges[fr].size(); k++)
{
q.push(edges[fr][k]);
}
}
}
}
在这个版本中,节点只有在从堆栈中取出时才会被标记。请注意,检查节点是否已被访问是必要的,因为堆栈上的节点可能会被稍后的迭代访问。此实现产生序列
1 2 4 8 7 3 6 5
然而,这并不是描述为所需的解决方案。但是,请注意,如果没有额外的打破平局规则,DFS 算法允许访问顺序中存在一些歧义。顺序
1 2 4 8 5 6 3 7
可以通过将具有最小 id 的邻居最后压入堆栈来生成,从而在下一次迭代中访问它。