歐拉圖打印路徑 1375:騎馬修柵欄(fence)

【題目描述】
農民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

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long

using namespace std;
int n,du[505],g[505][505],x,y,mi=600,ma=0;
vector<int> a;

void dfs(int x)
{
    //printf("%d\n",x);
    for(int i=mi;i<=ma;i++)
    {
        if(g[x][i])
        {
            g[x][i]--,g[i][x]--;
            dfs(i);
        }
    }
    a.push_back(x);
}
int main()
{
    cin >> n;
    while(n--)
    {
        cin >> x >> y;
        du[x]++,du[y]++,g[x][y]++,g[y][x]++;//兩個點多條邊
        mi=min(mi,min(x,y));
        ma=max(ma,max(x,y));
    }
    int root=mi,i;
    for(i=mi;i<=ma;i++)
    {
        if(du[i]%2)
        {
            root=i;
            break;
        }
    }
    dfs(root);
    for(int i=a.size()-1;i>=0;i--)
        printf("%d\n",a[i]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章