1. 程式人生 > >演算法導論22.2-6:好選手、壞選手問題

演算法導論22.2-6:好選手、壞選手問題

Q:有兩種型別的職業摔跤選手:一種是好“選手”,一種是壞“選手”。對於任意一對摔跤職業選手來說,他們中可能有,也可能沒有比賽。假定有n位摔跤職業選手,並且有一份清單,上面列出了r對參加比賽的摔跤手。試給出一個o(n+r)時間的演算法,它能否確定是否指定某些摔跤手為好選手,而將餘下的摔跤手指定為壞選手,從而使得每一場比賽都是在一個好選手與一個壞選手之間進行。如果有可能做出這樣的指定,你的演算法就應該將它產生出來。

一、等價於判斷圖是否為二分圖(二著色)的問題

二分圖,就是頂點集V可分割為兩個互不相交的子集,並且圖中每條邊依附的兩個節點都分屬於這兩個互不相交的子集。如下圖所示:

二、判斷這個圖是不是二分圖

將好選手歸為一類,壞選手歸為一類。

若是某個圖為二分圖的話,當且僅當圖中所有的迴路都為偶數個頂點,頂點個數至少為2。因此,判斷圖中是否存在有奇數個頂點的迴路即可。判斷方法:

1、深度(或廣度)優先搜尋中,若兩個灰色節點有邊連線,且二者的深度(到根節點的距離)之和為偶數,則表明存在有奇數個頂點的迴路,即該圖不是二分圖。

2、如果該圖沒有迴路,那一定是可以二分的;若有迴路,則迴路中節點的度數一定 >=2。

統計每個節點的度數; 刪除所有度數<1的節點(將該節點對應的邊刪除,並將對應的頂點的度數-1); 然後將更新後的頂點度數為1的所有點加入隊列當中,對佇列中的每個元素重複上一步,即刪除度數為1的點。最後如果還有沒有被刪除的節點(即還存在度數>=2的節點),證明圖中存在迴路。如果全部都已刪除則圖中不存在迴路,即圖是二分的; 如果存在迴路,對剩下的每一個節點,統計從這個節點開始的所有迴路(DFS),並記錄路徑的長度,標記訪問狀態,如果存在奇數邊迴路就表明不是二分圖。否則,執行直到所有節點都被訪問完畢。