1. 程式人生 > >圖-尤拉路徑、歐拉回路

圖-尤拉路徑、歐拉回路

有一條名為Pregel的河流經過Konigsberg城。城中有7座橋。把河中的兩個島與河岸連線起來。當地居民熱衷於一個難題:是否存在於一條路線,可以不重複地走遍7座橋。這就是著名的七橋問題。它由大數學家尤拉首先提出,並給出了完美的解答。

尤拉首先把圖中的七橋問題用圖論的語言改寫成圖,則問題變成了:能否從無向圖中的一個結點出發走到一條道路,每條邊恰好經過一次。這樣的路線稱為尤拉道路。也可以形象的稱為一筆畫。

在尤拉道路中,進和出是對應的-除了起點和終點外,其他點的進出次數應該相等。換句話說,除了起點和終點外,其他點的度數(degree)應該是偶數。很可惜,在七橋問題中,所有4個點的度數均是奇數(這樣的點也稱奇點),因此不可能存在歐拉回路。上述條件也是充分條件-如果一個無向圖是連通的,且最多隻有兩個奇點,則一定存在歐拉回路。如果有兩個奇點,則必須從其中一個奇點出發,另一個奇點終止。如果奇點不存在,則可以從任意點出發,最終一定會回到該點(稱為歐拉回路

)。

用類似的推理方式可以得到有向圖的結論:最多隻能有兩個點的入度不等於出度,而且必須是其中一個點的出度恰好比入度大1(把它作為其起點),另一個的入度比出度大1(把它作為終點)。當然,還有一個前提條件:在忽略邊的方向後,圖必須是連通的。

總結一下。

尤拉路徑:

有向圖:最多隻能有兩個點的入度不等於出度,而且必須是其中一個點的出度恰好比入度大1,另一個的入度比出度大1,把它作為終點,當然在忽略邊的方向後,圖必須是連通的。

無向圖:有兩個奇點,從一個奇點出發,到達另一個奇點

歐拉回路:

有向圖存在歐拉回路的充要條件:所有頂點的入度等於出度且該圖是連通圖。

無向圖存在歐拉回路的充要條件:當且僅當該圖所有頂點度數都為偶數,且該圖是連通圖。

首先給出儲存結構:

int n, G[maxn][maxn];
bool vis[maxn][maxn];

有向圖的尤拉道路:

如果需要列印的是尤拉道路,在主程式中呼叫時,引數必須是道路的起點。另外,列印的順序是逆序的,因此在真正使用這份程式碼時,應當把printf語句替換成一條push語句,把邊壓入一個棧內。

void euler(int u)
{
    for(int v = 1; v <= n; v++)
        if(G[u][v] && !vis[u][v])
        {
            vis[u][v] = true; //有向圖去掉vis[v][u]
            euler(v);
            printf("%d %d\n",u, v);
        }
}