Problem Description
有一个地下迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关;请问如何从某个起点开始在迷宫中点亮所有的灯并回到起点?
Input
连续T组数据输入,每组数据第一行给出三个正整数,分别表示地下迷宫的结点数N(1 < N <= 1000)、边数M(M <= 3000)和起始结点编号S,随后M行对应M条边,每行给出一对正整数,表示一条边相关联的两个顶点的编号。
Output
若可以点亮所有结点的灯,则输出从S开始并以S结束的序列,序列中相邻的顶点一定有边,否则只输出部分点亮的灯的结点序列,最后输出0,表示此迷宫不是连通图。
访问顶点时约定以编号小的结点优先的次序访问,点亮所有可以点亮的灯后,以原路返回的方式回到起点。
Example Input
1
6 8 1
1 2
2 3
3 4
4 5
5 6
6 4
3 6
1 5
Example Output
1 2 3 4 5 6 5 4 3 2 1
题意:
利用深搜DFS (从头走到尾,走不动了,就回溯),将灯点亮,输出点亮的顺序和返回时的路径。是一个无向图的题目。dfs 模板题
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int e[1005][1005],book[1005];
int p[1005],ans;
int n,m;
int sum;
void dfs(int x)
{
int i;
p[ans++] = x;//点亮的路径
//printf("%d",x); //可以输出深搜的路径,与上面一样
sum++;
for(i=1;i<=n;i++)
{
//判断是否连通并且没有访问过
if(book[i] == 0 && e[x][i] == 1)
{
book[i] = 1; //记录该点已被访问过
dfs(i); //从该点开始搜
p[ans++] = x; //返回的路径,是x 不是i;
}
}
return ;
}
int main()
{
int T,s;
int a,b;
int i;
scanf("%d",&T);
while(T--)
{
sum = 0;
ans = 0;
scanf("%d%d%d",&n,&m,&s);
memset(book,0,sizeof(book));
memset(e,0,sizeof(e));
//建图
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
e[a][b] = e[b][a] = 1;
}
//先将开始的标记
book[s] = 1;
//开始搜索
dfs(s);
//输出格式,最后一个后面没空格
for(i=0;i<ans;i++)
{
if(i==0)
printf("%d",p[i]);
else
printf(" %d",p[i]);
}
//全部点亮,则输出换行
if(sum == n)
printf("\n");
//否则输出 0;
else
printf(" 0\n");
}
return 0;
}