kuangbin专题 专题二 搜索进阶 哈密顿绕行世界问题 HDU - 2181

 

题目链接:https://vjudge.net/problem/HDU-2181

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

思路:dfs和回溯,算一个基础题吧,这里需要邻接矩阵,用bool就可以,也可以用vector,数据小,就用前者了,直接看代码吧,写的比较详细

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <queue>
 5 #include <vector>
 6 #include <string>
 7 
 8 using namespace std;
 9 
10 #define inf (1LL << 31) - 1
11 #define rep(i,j,k) for(int i = j; i <= (k); i++)
12 #define rep__(i,j,k) for(int i = j; i < (k); i++)
13 #define per___(i,j,k) for(int i = j; i > (k); i--)
14 #define per(i,j,k) for(int i = j; i >= (k); i--)
15 
16 const int N = 30;
17 bool mp[N][N]; //邻接矩阵
18 int in;
19 bool vis[N]; //记录拜访过的城市,每个dfs的分支都需要一次初始化
20 int ans; 
21 
22 struct node{
23     int way[N]; //记录路线
24     int l; //长度
25     node(int a = 0){ l = a; }
26 };
27 
28 void input(){
29 
30     memset(mp, false, sizeof(mp));
31     int a, b, c;
32     rep(i, 1, 20){
33         cin >> a >> b >> c;
34         mp[i][a] = mp[i][b] = mp[i][c] = true;  //能到达的为true
35     }  
36 }
37 
38 void dfs(int now,node& rec){
39     
40     //拜访了所有的城市
41     if (rec.l == 20){
42         
43         //拜访的最后一个城市能不能回到初始城市
44         if (!mp[now][in]) return;
45         
46         //可以,输出答案
47         cout << (++ans) << ": ";
48         rep__(i, 0, rec.l) cout << " " << rec.way[i];
49         cout << " " << in << endl;
50         return;
51     }
52 
53     rep(i, 1, 20){
54         
55         //从小到大遍历城市编号,解决了字典序
56         //能到,没被拜访过
57         if (mp[now][i] == true && !vis[i]){
58             vis[i] = true;
59             rec.way[rec.l++] = i;
60             dfs(i, rec);
61             vis[i] = false;//(1)
62             rec.l--;       //(2)   (1)(2) 回溯
63         }
64     }
65 }
66 
67 int main(){
68 
69     input();
70 
71     node rec;
72 
73     while (cin >> in && in != 0){
74 
75         rec.way[rec.l++] = in; //记录开始的城市
76         vis[in] = true; //标记已经拜访过的城市
77         ans = 0;
78 
79         dfs(in,rec);
80     
81         rec.l = 0; //(1)
82         vis[in] = false; //(2)      (1)(2)回溯
83     }
84 
85     return 0;
86 }

 

 

 


 

posted @ 2019-07-10 15:49  SummerMingQAQ  阅读(219)  评论(0编辑  收藏  举报