acwing 4229. 哈密顿绕行世界问题(dfs)
题目描述
给定一个规则的实心十二面体,它共有 2020 个顶点,编号 1∼201∼20。
每个顶点都与三个其它顶点相邻。
给定十二面体的具体顶点分布,请你回答若干个问题。
每个问题给定一个出发点,请你求出从该点出发,经过所有顶点恰好一次,并回到出发点的所有可行路线。
输入格式
前 2020 行,每行包含三个整数,其中第 ii 行的整数表示与顶点 ii 相邻的三个顶点的编号。
接下来若干行,每行包含一个整数 mm,表示询问当出发点为 mm 时,从该点出发,经过所有顶点恰好一次,并回到出发点的所有可行路线。
当输入 m=0m=0 时,表示输入结束。
输出格式
每个询问按字典序输出所有可行路线,每个路线占一行,先输出这是该询问的第几条可行路线(从 11 开始),然后输出具体路线。
具体形式参考样例。
数据范围
每组数据最多 2020 个询问。
输入样例:
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
输出样例:
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
dfs搜索
分析
按照题目dfs即可
需要注意的是这里使用的邻接表存储邻边,所以插入到某个点的邻接表时,需要按编号从大到小插入,以保证遍历顺序是从小到大。
其实使用二维矩阵存储就够了~
int map[N][3]; // map[i][0]是第1个点,map[i][1]是第2个点,map[i][2]是第3个点,
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 100010;
int h[N], e[N], ne[N], idx = 0;
int k;
int path[30];
bool st[30];
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
int x;
void dfs(int step, int u)
{
path[step] = u;
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if(!st[j])
{
st[j] = true;
dfs(step+1, j);
st[j] = false;
}
if(j == x && step == 20)
{
k++;
printf("%d: ", k);
for(int i = 1; i <= 20; i++)
{
printf("%d ", path[i]);
}
printf("%d\n", x);
return;
}
}
}
int main()
{
memset(h, -1, sizeof h);
for(int i = 1; i <= 20; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
// 要使得a < b < c
int tc = max(a, max(b,c));
int ta = min(a, min(b, c));
int tb = (a + b + c) - (ta + tc);
add(i, tc);
add(i, tb);
add(i, ta);
}
while(cin >> x, x)
{
k = 0;
st[x] = true;
dfs(1, x);
st[x] = false;
}
}
时间复杂度
参考文章
https://blog.csdn.net/lp15203883326/article/details/52170215
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int map[25][5];
int vis[25];
int ans[25];
int cas=1;
int n.m;
void dfs(int num,int len)
{
int i,j;
vis[num]=1;
ans[len]=num;
for(i=0;i<3;i++)
{
int t=map[num][i];
if(t==m&&len==19)
{
printf("%d ",ans[j]);
printf("%d\n",m);
}
if(!vis[t])
dfs(t,len+1);
}
vis[num]=0;
}
int main()
{
int i,j;
for(i=1;i<=20;i++)
{
for(j=0;j<3;j++)
{
scanf("%d".&map[i][j]);
}
}
while(~scanf("%d",&m),m)
{
memset(vis,0,sizeof(vis));
dfs(m,0);
}
return 0;
}