HDU2181:哈密顿绕行世界问题(DFS路径输出)
题意:这个十二面体上的顶点也相当于是个图,每个节点是连接着周围3个顶点,构成的一个环图。问从一个点出发,能有多少种走法能从起点走到起点,每个节点都必须走一次。
思路:是dfs无疑,我一般看到dfs存路径,我就想到了用链表来存路径,走一步存一步,到达了终点,就输出链表路径。回溯一步,链表弹一步。
但是这个题,当时要字典序输出路径,我就先想着先无序做做看,结果数据走的就是字典序。
代码细节:1:因为这是图啊,是要开vis数组的。
2:我dfs遍历,喜欢在dfs形参上增添当前节点'st'和其它性质,这个题要求每个节点都走满,我肯定在添一个变量'num',表示走了多少节点,num==20 才会输出路径的。
3:注意回溯的位置,是在for里面的,我当时就混淆回溯的位置,for跑了其中一个点,回溯了vis[x]=0,这个for是不会再重复跑这个节点的,for遍历难道会回头吗?
4:存图是单向图啊,不会存在倒着跑
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=25;
vector<int>G[N];
vector<int>vis(N,0);
list<int>li;
int w,cnt=0,ans=0;//ans:每个城市都访问过
void dfs(int st,int num){
vis[st]=1;
for(auto x:G[st]){
if(vis[x]&&x==w&&num==20){
cout<<++cnt<<":"<<" ";
for(auto a:li){
cout<<a<<" ";
}
cout<<w;
cout<<endl;
}
if(vis[x]) continue;
vis[x]=1;
li.push_back(x);
dfs(x,++num);
vis[x]=0;//回溯
--num;
li.pop_back();
}
}
int main()
{
int a,b,c;
for(int i=1;i<=20;i++){
cin>>a>>b>>c;
G[i].push_back(a);//单向图
G[i].push_back(b);
G[i].push_back(c);
}
while(scanf("%lld",&w) && w!=0){
fill(vis.begin(),vis.end(),0);
li.clear();
ans=0;
li.push_back(w);
++ans;
dfs(w,ans);
}
return 0;
}
浙公网安备 33010602011771号