第三部分 數據結構 --第四章 圖論算法1375:騎馬修柵欄(fence)

1375:騎馬修柵欄(fence)

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 5898 通過數: 1666
【題目描述】
農民John每年有很多柵欄要修理。他總是騎着馬穿過每一個柵欄並修復它破損的地方。

John是一個與其他農民一樣懶的人。他討厭騎馬,因此從來不兩次經過一個一個柵欄。你必須編一個程序,讀入柵欄網絡的描述,並計算出一條修柵欄的路徑,使每個柵欄都恰好被經過一次。John能從任何一個頂點(即兩個柵欄的交點)開始騎馬,在任意一個頂點結束。

每一個柵欄連接兩個頂點,頂點用1到500標號(雖然有的農場並沒有500個頂點)。一個頂點上可連接任意多(≥1)個柵欄。所有柵欄都是連通的(也就是你可以從任意一個柵欄到達另外的所有柵欄)。

你的程序必須輸出騎馬的路徑(用路上依次經過的頂點號碼錶示)。我們如果把輸出的路徑看成是一個500進制的數,那麼當存在多組解的情況下,輸出500進製表示法中最小的一個 (也就是輸出第一個數較小的,如果還有多組解,輸出第二個數較小的,等等)。 輸入數據保證至少有一個解。

【輸入】
第1行:一個整數F(1≤F≤1024),表示柵欄的數目;

第2到F+1行:每行兩個整數i,j(1≤=i,j≤500)表示這條柵欄連接i與j號頂點。

【輸出】
輸出應當有F+1行,每行一個整數,依次表示路徑經過的頂點號。注意數據可能有多組解,但是隻有上面題目要求的那一組解是認爲正確的。

【輸入樣例】
9
1 2
2 3
3 4
4 2
4 5
2 5
5 6
5 7
4 6
【輸出樣例】
1
2
3
4
2
5
4
6
5
7


思路:找歐拉回路,從1~500深搜。找出歐拉路的方法就是採用深搜的方式,對於當前的點,把所有點從小到大的搜索,找到和它相連的,找到一個之後刪除它們之間的連線,並去搜索新的那個點,如果沒有找到點和它相連,那麼就把這個點加入輸出隊列

#include<cstdio>
using namespace std;
int a[999][999];//鄰接矩陣存儲,i->j共有多少條柵欄
int n,m;
int z = 1;
int b[9999];
int t = 0;
int du[9999];//每個點的度 也就是有多少條變與其連接
void dfs(int x)
{
    int i;
    for(i = 1;i <= 500;i++)//從小到大尋找
    {
        if(a[x][i] != 0)//有邊沒走過就走
        {
        a[x][i]--;//將這個邊刪去,避免重複
        a[i][x]--;
        dfs(i);
        }
    }
    b[++t] = x;//記錄走過的路徑
}
int main()
{
    scanf("%d",&n);
    for(int i = 1;i <= n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        a[x][y]++;//鄰接矩陣存圖
        a[y][x]++;//兩點之間可能有多條邊連接,所有要用++
        du[x]++;//記錄度
        du[y]++;
    }
    for(int i = 1;i <= 500;i++)
 
    {
        if(du[i]%2 == 1){
        z = i;break;  //找奇點
        }
    }
    dfs(z);//從起點開始
    for(int i = t;i >= 1;i--) printf("%d\n",b[i]);//先深搜在記錄,答案順序是反過來的需倒着輸出
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章