1. 程式人生 > >SDUT-3361_資料結構實驗之圖論四:迷宮探索

SDUT-3361_資料結構實驗之圖論四:迷宮探索

資料結構實驗之圖論四:迷宮探索

Time Limit: 1000 ms Memory Limit: 65536 KiB

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

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

int s[1050][1050];/*利用鄰接矩陣來記錄圖*/
int n;/*n節點數量*/
int f[1050];/*記錄點是否被遍歷過*/
int S;/*起點*/
int pre[3050],num;/*記錄路徑*/

void DFS(int x)
{
    int i;
    f[x] = 1;
    pre[num++] = x;
    for(i=1;i<=n;i++)
    {
        if(!f[i]&&s[x][i])
        {
            DFS(i);
            pre[num++] = x;
        }
    }
}

int main()
{
    int t,m,i,j;
    scanf("%d",&t);
    while(t--)
    {
        memset(f,0,sizeof(f));
        scanf("%d%d%d",&n,&m,&S);
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                s[i][j] = i==j?1:0;
        for(i=0;i<m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            s[a][b] = s[b][a] = 1;
        }
        num = 0;
        DFS(S);
        printf("%d",pre[0]);
        for(i=1;i<num;i++)
            printf(" %d",pre[i]);
        if(num==2*n-1)
            printf("\n");
        else
            printf(" 0\n");

    }
    return 0;
}