https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=144
题意:给出一个n个结点的无向图以及某个结点k,按照字典序从小到大顺序输出从1到结点k的所有路径。
思路:如果直接矩阵深搜的话是会超时的,所以我们可以从终点出发,将与终点相连的连通块保存起来,这样dfs深搜时可以剪枝掉一些到达不了的点。只要解决了这个,dfs就是小问题。
这道题还有点坑的就是输出格式和它所给的格式不一样,注意一下。
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 const int maxn = 22; 6 7 int n, step, route; 8 int map[maxn][maxn]; 9 int path[maxn]; 10 int vis[maxn]; 11 int trunk[maxn]; 12 13 void init(int cur) //从终点开始遍历,保存与终点相连的连通块 14 { 15 trunk[cur] = 1; 16 for (int i = 1; i < maxn; i++) 17 { 18 if (map[cur][i] && !trunk[i]) 19 init(i); 20 } 21 } 22 23 void dfs(int cur, int step) 24 { 25 if (cur == n) 26 { 27 cout << "1"; 28 for (int i = 1; i < step; i++) 29 cout << " " << path[i]; 30 cout << endl; 31 memset(path, 0, sizeof(0)); 32 route++; 33 } 34 for (int i = 0; i < maxn; i++) 35 { 36 if (map[cur][i] && !vis[i] && trunk[i]) 37 { 38 vis[i] = 1; 39 path[step] = i; 40 dfs(i, step + 1); 41 vis[i] = 0; 42 } 43 } 44 return; 45 } 46 47 int main() 48 { 49 //freopen("D:\txt.txt", "r", stdin); 50 int a, b, kase = 0; 51 while (cin >> n && n) 52 { 53 memset(vis, 0, sizeof(vis)); 54 memset(map, 0, sizeof(map)); 55 memset(path, 0, sizeof(path)); 56 memset(trunk, 0, sizeof(trunk)); 57 while (cin >> a >> b) 58 { 59 if (!a && !b) break; 60 map[a][b] = map[b][a] = 1; 61 } 62 vis[1] = 1; 63 step = 1; 64 route = 0; //记录路径数量 65 init(n); //计算保存连通块 66 cout << "CASE " << ++kase << ":" << endl; 67 dfs(1, 1); 68 cout << "There are " << route << " routes from the firestation to streetcorner " << n << "." << endl; 69 70 } 71 return 0; 72 }