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

来源:互联网 发布:淘宝怎样进行实名认证 编辑:程序博客网 时间:2024/06/06 21:09

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

#include <iostream>#include <cstring>using namespace std;int map[1010][1010];int visit[1010];int ans[1010];int n, m, s;int p;void DFS(int x){    visit[x] = 1;    ans[p++] = x;    for(int i = 1; i <= n; i++)    {        if(map[x][i] == 1 && visit[i] != 1)        {            if(i == 1)            {                break;            }            DFS(i);            ans[p++] = x;//存返回去的路        }    }}int main(){   int t;   cin>>t;   int u, v;   while(t--)   {       memset(map, 0, sizeof(map));       memset(visit, 0, sizeof(visit));       cin>>n>>m>>s;       for(int i = 0; i < m; i++)       {           cin>>u>>v;           map[u][v] = map[v][u] = 1;       }       p = 0;       DFS(s);       if(p == 2 * n - 1)       {           for(int i = 0; i < p; i++)           {               if(i == 0)                cout<<ans[i];               else                cout<<" "<<ans[i];           }           cout<<endl;       }       else       {           for(int i = 0; i < p ; i++)           {               if(i == 0)                cout<<ans[i];               else                cout<<" "<<ans[i];           }           cout<<" "<<"0"<<endl;       }   }    return 0;}
//迷宫探索:用深度,存走过的结点次序还要包括返回的结点次序#include <iostream>#include <cstdio>#include <cstring>using namespace std;int n, m, s, a, b, p;int map[1100][1100];int visit[1100];int ans[1100];void dfs(int x){    visit[x] = 1;    ans[p++] = x;    for(int i = 1; i <= n; i++)//visit数组从1开始存    {        if(map[x][i] == 1 && visit[i] != 1)        {            //ans[num++]=i;记录dfs遍历点的顺序            visit[i] = 1;            dfs(i);//只有递归到不能再递归了,说明已经递归到最后一个数,即终点            ans[p++] = x;//记录“来"的时候遍历序列        }    }}int main(){    int t;    cin>>t;    while(t--)    {        memset(map, 0, sizeof(map));        memset(visit, 0, sizeof(visit));        cin>>n>>m>>s;//n为结点数,m为边数        for(int i = 0; i < m; i++)        {            cin>>a>>b;            map[a][b] = map[b][a] = 1;        }        p = 0;        dfs(s);        for(int i = 0; i < p; i++)        {            if(i == 0)                cout<<ans[i];            else                cout<<" "<<ans[i];        }        if(p != 2 * n - 1)//来回两次,最后一点点只访问一次。所以为2*n-1            cout<<" "<<"0";        cout<<endl;    }    return 0;}
原创粉丝点击