淺談歐拉回路與歐拉路徑

§概念
歐拉環:圖中經過每條邊一次且僅一次的環;
歐拉路徑:圖中經過每條邊一次且僅一次的路徑;
歐拉圖:有至少一個歐拉環的圖;
半歐拉圖:沒有歐拉環,但有至少一條歐拉路徑的圖。

基圖:對一個圖而言把所有邊視作無向邊得到其基圖。即將所有有向邊變成無向邊形成的無向圖


  這裏扯一點題外話,相信大家在小學課本里面都看到過一個叫做七橋問題的東西,好像是歐拉解決了這個問題,並且歐拉對一般情形也有深入的研究,所以一筆畫問題的解決就是求圖中的歐拉什麼什麼,名字貌似是這麼來的。

  

§說明
感覺自己已經不會寫Euler了,有些路徑我早已忘記……所以決定寫這麼一個東西。當自己看到SGU101的時候,覺得自己好像只會寫最簡單的版本了!所以寫了這個東西。


§各種情況【許多是參看以前的課件和旁邊的鏈接】歐拉路徑
【引理】
除了S、T之外的任何點一定滿足進入次數等於出去次數! 好吧,這個感覺就像一些奇怪的東西,待會兒會用到,先記住吧!

【無向圖】
一個無向圖是歐拉圖當且僅當該圖是連通的(注意,不考慮圖中度爲0的點,因爲它們的存在對於圖中是否存在歐拉環、歐拉路徑沒有影響)且所有點的度數都是偶數;一個無向圖是半歐拉圖當且僅當該圖是連通的且有且只有2個點的度數是奇數(此時這兩個點只能作爲歐拉路徑的起點和終點);

證明:因爲任意一個點,歐拉環(或歐拉路徑)從它這裏進去多少次就要出來多少次,故(進去的次數+出來的次數)爲偶數,又因爲(進去的次數+出來的次數)=該點的度數(根據定義),所以該點的度數爲偶數。


【有向圖】
一個有向圖是歐拉圖當且僅當該圖的基圖(這裏同樣不考慮度數爲0的點)是連通的且所有點的入度等於出度;一個有向圖是半歐拉圖當且僅當該圖的基圖是連通的且有且只有一個點的入度比出度少1(作爲歐拉路徑的起點),有且只有一個點的入度比出度多1(作爲終點),其餘點的入度等於出度。


【混合圖】
這個其實相當邪惡。

簡直就是虐殺,超級喪病!我們先來看前面的【引理】,我開始提到了這是一個奇怪的東西,沒錯,感覺這個引理同【網絡流】中的流量平衡/流守恆 (Flow Conservation)如出一轍。的確下面這個方法就用到了網絡流的相關知識。

顯然基圖不連通肯定不是歐拉圖
其實,難點在於圖中的無向邊,需要對所有的無向邊定向(指定一個方向,使之變爲有向邊),使整個圖變成一個有向歐拉圖(或有向半歐拉圖)。若存在一個定向滿足此條件,則原圖是歐拉圖(或半歐拉圖)否則不是。關鍵就是如何定向?


首先給原圖中的每條無向邊隨便指定一個方向(稱爲初始定向),將原圖改爲有向圖G',然後的任務就是改變G'中某些邊的方向(當然是無向邊轉化來的,原混合圖中的有向邊不能動)使其滿足每個點的入度等於出度。
設D[i]爲G'中(點i的出度 - 點i的入度)。可以發現,在改變G'中邊的方向的過程中,任何點的D值的奇偶性都不會發生改變(設將邊<i, j>改爲<j, i>,則i入度加1出度減1,j入度減1出度加1,兩者之差加2或減2,奇偶性不變)!而最終要求的是每個點的入度等於出度,即每個點的D值都爲0,是偶數,故可得:若初始定向得到的G'中任意一個點的D值是奇數,那麼原圖中一定不存在歐拉環!


若初始D值都是偶數,則將G'改裝成網絡:設立源點S和匯點T,對於每個D[i]>0的點i,連邊<S, i>,容量爲D[i]/2;對於每個D[j]<0的點j,連邊<j, T>,容量爲-D[j]/2;G'中的每條邊在網絡中仍保留,容量爲1(表示該邊最多隻能被改變方向一次)。求這個網絡的最大流,若S引出的所有邊均滿流,則原混合圖是歐拉圖,將網絡中所有流量爲1的中間邊(就是不與S或T關聯的邊)在G'中改變方向,形成的新圖G''一定是有向歐拉圖;若S引出的邊中有的沒有滿流,則原混合圖不是歐拉圖。


爲什麼能這樣建圖?
考慮網絡中的一條增廣路徑S-->i-->...-->j-->T,將這條從i到j的路徑在G'中全部反向,則:i的入度加1出度減1,j的入度減1出度加1,路徑中其它點的入度出度均不變。而i是和S相連的,因此初始D[i]>0,即i的出度大於入度,故這樣反向之後D[i]減少2;同理,j是和T相連的,這樣反向之後D[j]增加2。因此,若最大流中邊<S, i>滿流(流量爲初始D[i]/2),此時D[i]值就變成了0,也就是i的入度等於出度。因此只要使所有S引出的邊全部滿流,所有初始D值>0的點的D值將等於0,又因爲將邊變向後所有點的D值之和不變,所有初始D值小於0的點的D值也將等於0,而初始D值等於0的D點既不與S相連也不與T相連,所以它們是網絡中的中間點,而中間點的流入量等於流出量,故它們的入度和出度一直不變,即D值一直爲0。因此,整個圖G'成爲歐拉圖。


(2)歐拉路徑的判定:
首先可以想到的是枚舉歐拉路徑的起點i和終點j,然後在圖中添加邊<j, i>,再求圖中是否有歐拉回路即可。但是,該算法的時間複雜度達到了O(M * 最大流的時間),需要優化。
前面已經說過,在將邊變向的過程中任何點的D值的奇偶性都不會改變,而一個有向圖有歐拉路徑的充要條件是基圖連通且有且只有一個點的入度比出度少1(作爲歐拉路徑的起點),有且只有一個點的入度比出度多1(作爲終點),其餘點的入度等於出度。這就說明,先把圖中的無向邊隨便定向,然後求每個點的D值,若有且只有兩個點的初始D值爲奇數,其餘的點初始D值都爲偶數,則有可能存在歐拉路徑(否則不可能存在)。進一步,檢查這兩個初始D值爲奇數的點,設爲點i和點j,若有D[i]>0且D[j]<0,則i作起點j作終點(否則若D[i]與D[j]同號則不存在歐拉路徑),連邊<j, i>,求是否存在歐拉環即可(將求出的歐拉環中刪去邊<j, i>即可)。這樣只需求一次最大流。


【小結】

其實圖論算法本身並不是非常的可怕,大部分的代碼都有成品可以大肆利用。但是圖論最重要的應該是在建模方面:

下面來看坑了蒟蒻我的SGU101

額,題目大意是什麼domino,英語蒟蒻的我看了一天才知道是多米諾。

多米諾骨牌,一種用小的方的木塊或其他材料,每個都被一些點在面上標記,這些木塊通常被稱爲骨牌。每個骨牌的面都被一條線分成兩個方形,兩邊各有一定點數。N個多米諾骨牌,每個骨牌左右兩側分別有一個0~6的整數(骨牌可以旋轉以調換其左右兩數),求一種把這些骨牌從左到右排列的方案,使得所有相鄰的兩數字相等(即左邊骨牌右側的數字等於右邊骨牌左側的數字)。

題目值得思考,中點在於如何構造邊和點:

 將0~6這7種牌面看作節點,把骨牌看作是連接兩節點的無向弧,這樣就組成了一個無向圖(當然可能有重邊),圖中的一條歐拉路就對應一種方案。
   歐拉路的構造方法:若圖連同且度爲奇數的節點不超過兩個,則可以構造出歐拉路。先選一個度爲奇數的節點(若沒有就任選一個度爲偶數的節點),以該節點爲起點,深搜遍歷所有的弧(每條弧只遍歷一次),在每次回溯時將當前弧記錄下來,記錄的弧的排列就組成了一條歐拉路。
   實際編程時,爲便於輸出方案,可將圖中的邊加上一個“權值”,爲骨牌的編號。
蒽,大體就是如此。感覺我還是水了。

對於我WA過的數據進行解釋

[WA]
test 5 呵呵自動把編號當做是否要反轉,這也能過前面的點我也是醉了
test 1 對於這一塊而言下一塊的反轉應該與這一塊不同。。。

【補例】

下面這道題是ACM的某題,也考慮到了構圖是邊和點的選擇從而導致圖的不同

有N個盤子,每個盤子上寫着一個僅由小寫字母組成的英文單詞。
你需要給這些盤子按照合適的順序排成一行,使得相鄰兩個盤子中,前一個盤子上面單詞的末字母等於後一個盤子上面單詞的首字母。
請你編寫一個程序,判斷是否能達到這一要求。如果能,請給出一個合適的順序。

【模型1】

將每個盤子看作一個頂點。
如果盤子B能連接在盤子A後面,那麼從A向B連一條有向邊。


問題轉化爲在圖中尋找一條不重複地經過所有頂點的路徑,即哈密爾頓路。
但是,求哈密爾頓路是一個十分困難的問題,豈止是困難,簡直是嚇人,這樣的建模沒有給解題帶來任何便利。我們必須另闢蹊徑。

【模型2】

當然模型2 就應運而生。

以26個英文字母作爲頂點。
對於每一個單詞,在圖中從它的首字母向末字母連一條有向邊。


然後求歐拉路徑就可以了。

好吧。這只是一個淺析,我畢竟大概確實是一個蒟蒻。希望大家能看懂。



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