数据结构实验之图论四:迷宫探索

心已入冬 提交于 2019-11-26 06:47:36

Problem Description

有一个地下迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关;请问如何从某个起点开始在迷宫中点亮所有的灯并回到起点?

Input

连续T组数据输入,每组数据第一行给出三个正整数,分别表示地下迷宫的结点数N(1 < N <= 1000)、边数M(M <= 3000)和起始结点编号S,随后M行对应M条边,每行给出一对正整数,表示一条边相关联的两个顶点的编号。

 

Output

若可以点亮所有结点的灯,则输出从S开始并以S结束的序列,序列中相邻的顶点一定有边,否则只输出部分点亮的灯的结点序列,最后输出0,表示此迷宫不是连通图。
访问顶点时约定以编号小的结点优先的次序访问,点亮所有可以点亮的灯后,以原路返回的方式回到起点。

Sample Input

1
6 8 1
1 2
2 3
3 4
4 5
5 6
6 4
3 6
1 5

Sample Output

1 2 3 4 5 6 5 4 3 2 1

Hint

 

Source

xam

解题思路:这道题其实就是对图进行一遍dfs,然后用一个数组来把dfs的顺序来存储起来。

代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int map[1011][1011] ; //记录节点之间的关系
int vis[1011] ; //记录节点是否被使用
int n, m ; //节点数、边数
int count ; //
int t ; //起始编号
int s[2011] ; //存储数组

void dfs(int t)
{
    int  i ;
    vis[t] =1 ;
    s[count++] = t;
    for(i = 1 ; i<=n;i++)
    {
        if(!vis[i]&&map[t][i])
        {
            dfs(i);
            s[count++] = t;
        }
    }
}

int main()
{
    int p ; //记录输入的组数
    int i ;
    scanf("%d",&p) ;
    while(p--)
    {
        //初始化数据
        memset(vis,0,sizeof(vis)) ;
        memset(map,0,sizeof(map)) ;
        count = 0 ;
        scanf("%d %d %d",&n,&m,&t) ;
        while(m--)
        {
            int in , out ;
            scanf("%d %d",&in,&out) ;
            map[in][out] =map[out][in] = 1;
        }
        dfs(t) ;
        for(i =0 ;i<count ;i++)
        {
            if(i == 0)
                printf("%d",s[i]) ;
           else  printf(" %d",s[i]) ;
        }
        if(count==2*n-1)
        {
            printf("\n") ;
        }
        else printf(" 0\n") ;
    }
    return 0 ;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!