HDU 2181 哈密顿绕行世界问题 dfs 难度:1
http://acm.hdu.edu.cn/showproblem.php?pid=2181
只有20个城市,而且每个点的度数恰好是3,也就意味着,对于即将进入环中的点,入度1,出度2,下一个点只有两种可能
暴力枚举出所有的路径,也不过3*2^18,之后对于每个点作为起点的情况分别调整即可
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int e[21][3]; bool vis[21]; struct circle{ int a[20]; circle(){} circle(int b[20]){ for(int i=0;i<20;i++)a[i]=b[i]; } bool operator <(circle c2)const {//便于按字典序排序 for(int i=0;i<20;i++){ if(a[i]<c2.a[i])return true; else if(a[i]>c2.a[i])return false; } return false; } void rot(int m){//调整成以m为起点 int ind=0; for(;ind<20&&a[ind]!=m;ind++){} int b[20]; for(int i=0;i<20;i++){ b[i]=a[(i+ind)%20]; } for(int i=0;i<20;i++){ a[i]=b[i]; } } }c[100000]; int cnum; int heap[20]; void dfs(int s,int f,int cnt){ vis[s]=true; heap[cnt-1]=s; if(cnt==20){ for(int i=0;i<3;i++){ if(e[s][i]==f){ c[cnum++]=circle(heap); } } vis[s]=false; return ; } for(int i=0;i<3;i++){ if(!vis[e[s][i]]){ dfs(e[s][i],f,cnt+1); } } vis[s]=false; } int main(){ int m; for(int i=1;i<=20;i++){ for(int j=0;j<3;j++){ scanf("%d",e[i]+j); } } dfs(1,1,1); while(scanf("%d",&m)==1&&m!=0){ for(int i=0;i<cnum;i++){ c[i].rot(m); } sort(c,c+cnum); for(int i=0;i<cnum;i++){ printf("%d: ",i+1); for(int j=0;j<20;j++){ printf("%d ",c[i].a[j]); } printf("%d\n",m); } } return 0; }