HDU2181 哈密顿绕行世界问题 —— DFS

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2181


 

哈密顿绕行世界问题

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5132    Accepted Submission(s): 3091

Problem Description
一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市。 
 

 

Input
前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出.
 

 

Output
输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output
 

 

Sample Input
2 5 20 1 3 12 2 4 10 3 5 8 1 4 6 5 7 19 6 8 17 4 7 9 8 10 16 3 9 11 10 12 15 2 11 13 12 14 20 13 15 18 11 14 16 9 15 17 7 16 18 14 17 19 6 18 20 1 13 19 5 0
 

 

Sample Output
1: 5 1 2 3 4 8 7 17 18 14 15 16 9 10 11 12 13 20 19 6 5 2: 5 1 2 3 4 8 9 10 11 12 13 20 19 18 14 15 16 17 7 6 5 3: 5 1 2 3 10 9 16 17 18 14 15 11 12 13 20 19 6 7 8 4 5 4: 5 1 2 3 10 11 12 13 20 19 6 7 17 18 14 15 16 9 8 4 5 5: 5 1 2 12 11 10 3 4 8 9 16 15 14 13 20 19 18 17 7 6 5 6: 5 1 2 12 11 15 14 13 20 19 18 17 16 9 10 3 4 8 7 6 5 7: 5 1 2 12 11 15 16 9 10 3 4 8 7 17 18 14 13 20 19 6 5 8: 5 1 2 12 11 15 16 17 18 14 13 20 19 6 7 8 9 10 3 4 5 9: 5 1 2 12 13 20 19 6 7 8 9 16 17 18 14 15 11 10 3 4 5 10: 5 1 2 12 13 20 19 18 14 15 11 10 3 4 8 9 16 17 7 6 5 11: 5 1 20 13 12 2 3 4 8 7 17 16 9 10 11 15 14 18 19 6 5 12: 5 1 20 13 12 2 3 10 11 15 14 18 19 6 7 17 16 9 8 4 5 13: 5 1 20 13 14 15 11 12 2 3 10 9 16 17 18 19 6 7 8 4 5 14: 5 1 20 13 14 15 16 9 10 11 12 2 3 4 8 7 17 18 19 6 5 15: 5 1 20 13 14 15 16 17 18 19 6 7 8 9 10 11 12 2 3 4 5 16: 5 1 20 13 14 18 19 6 7 17 16 15 11 12 2 3 10 9 8 4 5 17: 5 1 20 19 6 7 8 9 10 11 15 16 17 18 14 13 12 2 3 4 5 18: 5 1 20 19 6 7 17 18 14 13 12 2 3 10 11 15 16 9 8 4 5 19: 5 1 20 19 18 14 13 12 2 3 4 8 9 10 11 15 16 17 7 6 5 20: 5 1 20 19 18 17 16 9 10 11 15 14 13 12 2 3 4 8 7 6 5 21: 5 4 3 2 1 20 13 12 11 10 9 8 7 17 16 15 14 18 19 6 5 22: 5 4 3 2 1 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 23: 5 4 3 2 12 11 10 9 8 7 6 19 18 17 16 15 14 13 20 1 5 24: 5 4 3 2 12 13 14 18 17 16 15 11 10 9 8 7 6 19 20 1 5 25: 5 4 3 10 9 8 7 6 19 20 13 14 18 17 16 15 11 12 2 1 5 26: 5 4 3 10 9 8 7 17 16 15 11 12 2 1 20 13 14 18 19 6 5 27: 5 4 3 10 11 12 2 1 20 13 14 15 16 9 8 7 17 18 19 6 5 28: 5 4 3 10 11 15 14 13 12 2 1 20 19 18 17 16 9 8 7 6 5 29: 5 4 3 10 11 15 14 18 17 16 9 8 7 6 19 20 13 12 2 1 5 30: 5 4 3 10 11 15 16 9 8 7 17 18 14 13 12 2 1 20 19 6 5 31: 5 4 8 7 6 19 18 17 16 9 10 3 2 12 11 15 14 13 20 1 5 32: 5 4 8 7 6 19 20 13 12 11 15 14 18 17 16 9 10 3 2 1 5 33: 5 4 8 7 17 16 9 10 3 2 1 20 13 12 11 15 14 18 19 6 5 34: 5 4 8 7 17 18 14 13 12 11 15 16 9 10 3 2 1 20 19 6 5 35: 5 4 8 9 10 3 2 1 20 19 18 14 13 12 11 15 16 17 7 6 5 36: 5 4 8 9 10 3 2 12 11 15 16 17 7 6 19 18 14 13 20 1 5 37: 5 4 8 9 16 15 11 10 3 2 12 13 14 18 17 7 6 19 20 1 5 38: 5 4 8 9 16 15 14 13 12 11 10 3 2 1 20 19 18 17 7 6 5 39: 5 4 8 9 16 15 14 18 17 7 6 19 20 13 12 11 10 3 2 1 5 40: 5 4 8 9 16 17 7 6 19 18 14 15 11 10 3 2 12 13 20 1 5 41: 5 6 7 8 4 3 2 12 13 14 15 11 10 9 16 17 18 19 20 1 5 42: 5 6 7 8 4 3 10 9 16 17 18 19 20 13 14 15 11 12 2 1 5 43: 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 44: 5 6 7 8 9 16 17 18 19 20 1 2 12 13 14 15 11 10 3 4 5 45: 5 6 7 17 16 9 8 4 3 10 11 15 14 18 19 20 13 12 2 1 5 46: 5 6 7 17 16 15 11 10 9 8 4 3 2 12 13 14 18 19 20 1 5 47: 5 6 7 17 16 15 11 12 13 14 18 19 20 1 2 3 10 9 8 4 5 48: 5 6 7 17 16 15 14 18 19 20 13 12 11 10 9 8 4 3 2 1 5 49: 5 6 7 17 18 19 20 1 2 3 10 11 12 13 14 15 16 9 8 4 5 50: 5 6 7 17 18 19 20 13 14 15 16 9 8 4 3 10 11 12 2 1 5 51: 5 6 19 18 14 13 20 1 2 12 11 15 16 17 7 8 9 10 3 4 5 52: 5 6 19 18 14 15 11 10 9 16 17 7 8 4 3 2 12 13 20 1 5 53: 5 6 19 18 14 15 11 12 13 20 1 2 3 10 9 16 17 7 8 4 5 54: 5 6 19 18 14 15 16 17 7 8 9 10 11 12 13 20 1 2 3 4 5 55: 5 6 19 18 17 7 8 4 3 2 12 11 10 9 16 15 14 13 20 1 5 56: 5 6 19 18 17 7 8 9 16 15 14 13 20 1 2 12 11 10 3 4 5 57: 5 6 19 20 1 2 3 10 9 16 15 11 12 13 14 18 17 7 8 4 5 58: 5 6 19 20 1 2 12 13 14 18 17 7 8 9 16 15 11 10 3 4 5 59: 5 6 19 20 13 12 11 10 9 16 15 14 18 17 7 8 4 3 2 1 5 60: 5 6 19 20 13 14 18 17 7 8 4 3 10 9 16 15 11 12 2 1 5
 

 

Author
Zhousc
 

 

Source

 

 




题解:

有20个点,每个点与3个点连接。如果使用回溯的话,操作次数是:2^20  约等于1e6(实际上要小),所以可以直接dfs回溯。

写法一:由于要回到初始点,所以要走21个点,且vis过的点还要进去试试:是不是最后一个点且为初始点。;

写法二:vis过的点不再访问,当走到第20点时,如果第20个点与起始点相连,那么就能回到起始点。



写法一:

 1 #include <iostream>  
 2 #include <cstdio>  
 3 #include <cstring>  
 4 #include <cmath>  
 5 #include <algorithm>  
 6 #include <vector>  
 7 #include <queue>  
 8 #include <stack>  
 9 #include <map>  
10 #include <string>  
11 #include <set>  
12 #define ms(a,b) memset((a),(b),sizeof((a)))  
13 using namespace std;  
14 typedef long long LL;  
15 const int INF = 2e9;  
16 const LL LNF = 9e18;  
17 const int MOD = 1e9+7;  
18 const int MAXN = 20+10;  
19   
20 int g[MAXN][3];  
21 int vis[MAXN], path[MAXN], cnt, m;  
22   
23 void dfs(int u, int k)  
24 {  
25     if(k==20+1)  //到了最后一个点
26     {  
27         if(u==m)  //回到了出发点
28         {  
29             printf("%d:  ", ++cnt);  
30             for(int i = 1; i<=20; i++)  
31                 printf("%d ", path[i]);  
32             printf("%d\n", m);  
33         }  
34         return;  
35     }  
36     if(vis[u]) return;      //没有到达最后一个点,并且vis过的,都要退出
37   
38     vis[u] = 1;  
39     path[k] = u;  
40     for(int i = 0; i<3; i++)   //因为要回到出发点,所以vis过的也要再试一试:是不是最后一个点且是出发点
41         dfs(g[u][i], k+1);  
42     vis[u] = 0;  
43 }  
44   
45 int main()  
46 {  
47     for(int i = 1; i<=20; i++)  
48     {  
49         for(int j = 0; j<3; j++)  
50             scanf("%d",&g[i][j]);  
51         sort(g[i], g[i]+3);     //保证按字典序输出
52     }  
53   
54     while(scanf("%d",&m) && m)  
55     {  
56         ms(vis, 0);  
57         cnt = 0;  
58         dfs(m, 1);  
59     }  
60 }
View Code


写法二:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 #define ms(a,b) memset((a),(b),sizeof((a)))
13 using namespace std;
14 typedef long long LL;
15 const int INF = 2e9;
16 const LL LNF = 9e18;
17 const int MOD = 1e9+7;
18 const int MAXN = 20+10;
19 
20 int g[MAXN][3];
21 int vis[MAXN], path[MAXN], cnt, m;
22 
23 void dfs(int u, int k)
24 {
25     path[k] = u;    //记录路径
26     if(k==20)  //到了倒数第二个点
27     {
28         for(int i = 0; i<3; i++)    //如果与初始点相连,那么就可以回到初始点
29         if(g[u][i]==m)
30         {
31             printf("%d:  ", ++cnt);
32             for(int i = 1; i<=20; i++)
33                 printf("%d ", path[i]);
34             printf("%d\n", m);
35         }
36         return;
37     }
38 
39     vis[u] = 1;
40     for(int i = 0; i<3; i++)
41         if(!vis[g[u][i]])
42             dfs(g[u][i], k+1);
43     vis[u] = 0;
44 }
45 
46 int main()
47 {
48     for(int i = 1; i<=20; i++)
49     {
50         for(int j = 0; j<3; j++)
51             scanf("%d",&g[i][j]);
52         sort(g[i], g[i]+3);     //保证按字典序输出
53     }
54 
55     while(scanf("%d",&m) && m)
56     {
57         ms(vis, 0);
58         cnt = 0;
59         dfs(m, 1);
60     }
61 }
View Code

 


 

posted on 2017-09-03 21:09  h_z_cong  阅读(142)  评论(0编辑  收藏  举报

导航