LINK
一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市。
Input
前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出.
Output
输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.
分析:十二面体,每个点都和其他三个点相接;要求字典序输出,每站的连接站又是字典序给出,所以用for循环回溯;
AC代码1:
#include<stdio.h>
#include<string.h>
int g=1,m,t1,t2,t3;
int a[21][21],book[100],c[21],k;
void dfs(int ans,int x)
{
int i,j;
if(ans==19)
{
for(i=1;i<=3;i++)
{
if((a[x][i]==t1||a[x][i]==t2||a[x][i]==t3)&&!book[a[x][i]])//a指该站的其他连接点
{
c[19]=a[x][i];
printf("%d: ",k++);
for(j=0;j<=20;j++)
printf(" %d",c[j]);
printf("\n");
return;
}
}
return;//两个return不要忘记
}
for(i=1;i<=3;i++)
{
if(book[a[x][i]]==0)
{
c[ans]=a[x][i];
book[a[x][i]]=1;
dfs(ans+1,a[x][i]);
book[a[x][i]]=0;
}
}
}
int main()
{
int i,j;
for(i=1;i<=20;i++)
for(j=1;j<=3;j++)
scanf("%d",&a[i][j]);
while(scanf("%d",&m)&&m!=0)
{
t1=a[m][1];
t2=a[m][2];
t3=a[m][3];
memset(book,0,sizeof(book));
memset(c,0,sizeof(c));
k=1;
book[m]=1;
c[0]=m;
c[20]=m;
dfs(1,m);//1是控制第几站,m是哪一站
}
}
除此以外还可以将相连接的点用p[i][j]=1表示,但是复杂度较高;
AC代码2:
#include<stdio.h>
#include<string.h>
using namespace std;
int p[25][25];
int visit[25];
int ans[25];
int sum=1,n;
void dfs(int c,int t)
{
if(t==20&&p[c][n])
{
printf("%d: ",sum++);
for(int i=0;i<=20;i++)
{
printf(" %d",ans[i]);
}
printf("\n");
}
else
{
for(int i=1;i<=20;i++)
{
if(p[c][i]&&visit[i]==0)
{
visit[i]=1;
ans[t]=i;
dfs(i,t+1);
visit[i]=0;
}
}
}
}
int main()
{
memset(p,0,sizeof(p));
for(int i=1;i<=20;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
p[i][a]=p[i][b]=p[i][c]=p[a][i]=p[b][i]=p[c][i]=1;
}
while(~scanf("%d",&n)&&n)
{
memset(visit,0,sizeof(visit));
visit[n]=1;
ans[0]=n;
ans[20]=n;
dfs(n,1);
}
}```