白話最小邊覆蓋總結–附加 hdu1151結題報告

來源:互聯網
上載者:User

剛開始看到這個題目的時候就覺得想法很明了,就是不知道如何去匹配...

去網上看了不少人的解題報告,但是對於剛接觸“最小邊覆蓋”的我來說....還是很困難滴....於是自己又開始一如以往學習“最大獨立集”、“最小點覆蓋的”的思考方式啦:在瞭解一個看似高深的知識點之前,粗略瞭解這是個什麼東東,那麼看概念也會更好理解,(希望此部落格在自己以後回頭來看會一目明了,也對剛接觸“最小邊覆蓋”的人有協助(萬分感到榮幸)):

首先把題目的第一個案例圖形化(第一,圖形好理解,第二,很多人看到文字就煩啦。第三,圖論不畫圖怎麼可以捏),我們把交叉路看成點,街道看成邊,就如:

要求選擇最少的傘兵降落在某些交叉口,使他們走完所有的交叉口,(注意是單向邊)很容易選擇,我們在二號交叉口降落一個走到3再走到4,然後在1好交叉口降落一個,總共兩個就可以訪問所有的交叉口,我們就可以這樣看:把3號街道和1號街道看做一條邊,把2.3.4號交叉點都覆蓋啦:

這樣就對“最小邊覆蓋”有了那麼點粗俗的理解啦

接下來是解決這個問題,用匈牙利匹配:因為剛開始接觸二分匹配,我就想用街道(簡化為點)去和交叉口匹配:(誰知道...)

可想而知..完全不知道怎麼匹配....

接著就看看最小邊覆蓋和二分匹配的關係吧:(如果覺得看文字概念還是很煩..可以看下面的圖形說明,不過結合文字和圖形更有助理解)(摘自百度百科)

路徑覆蓋與二分圖匹配的關係(必須是沒有圈的有向圖): 最小路徑覆蓋=|P|-最大匹配數(|P|為定點數)其中最大匹配數的求法是把P中的每個頂點pi分成兩個頂點pi'與pj'',如果在p中存在一條pi到pj的邊,那麼在二分圖P'中就有一條串連pi'與pj''的無向邊;這裡pi' 就是p中pi的出邊,pj''就是p中pj 的一條入邊;對於公式:最小路徑覆蓋=|P|-最大匹配數;可以這麼來理解;如果匹配數為零,那麼P中不存在有向邊,於是顯然有:最小路徑覆蓋=|P|-最大匹配數=|P|-0=|P|;即P的最小路徑覆蓋數為|P|;P'中不在於匹配邊時,路徑覆蓋數為|P|;如果在P'中增加一條匹配邊pi'-->pj'',那麼在圖P的路徑覆蓋中就存在一條由pi串連pj的邊,也就是說pi與pj 在一條路徑上,於是路徑覆蓋數就可以減少一個;如此繼續增加匹配邊,每增加一條,路徑覆蓋數就減少一條;直到匹配邊不能繼續增加時,路徑覆蓋數也不能再減少了,此時就有了前面的公式;但是這裡只 是說明了每條匹配邊對應於路徑覆蓋中的一條路徑上的一條串連兩個點之間的有向邊;下面來說明一個路徑覆蓋中的每條串連兩個頂點之間的有向邊對應於一條匹配 邊;與前面類似,對於路徑覆蓋中的每條串連兩個頂點之間的每條有向邊pi--->pj,我們可以在匹配圖中對應做一條串連pi'與pj''的邊, 顯然這樣做出來圖的是一個匹配圖(這一點用反證法很容易證明,如果得到的圖不是一個匹配圖,那麼這個圖中必定存在這樣兩條邊 pi'---pj'' 及 pi' ----pk'',(j!=k),那麼在路徑覆蓋圖中就存在了兩條邊pi-->pj, pi--->pk ,那邊從pi出發的路徑就不止一條了,這與路徑覆蓋圖是矛盾的;還有另外一種情況就是存在pi'---pj'',pk'---pj'',這種情況也類似可證);至此,就說明了匹配邊與路徑覆蓋圖中串連兩頂點之間邊的一一對應關係,那麼也就說明了前面的公式成立!我們根據上面概念方法來畫圖....讓交叉點和交叉點點去匹配那麼圖中連線的意思就是:1號有一條路可以去3號,二號也有一條路去3號,三號有一條路去4號,可以想象1號2號我們可以來一個傘兵任意選一個走到3號...(一個匹配),然後從3號走到4號,就先1/2---->3------>4兩個匹配就走了三個點,剩下一個點就再來一個兵就可以啦。。。。那麼 最小邊覆蓋=|P|-最大匹配這個公式就比較明了啦....上馬,馬上來點解釋:
// 0MS 244K #include<stdio.h>#include<string.h>#define MAX 121int no_in,no_st;//交叉路的數量,街道數量bool map[MAX][MAX];//map[i][j]表示i號交叉口有一條街道可以達到j號交叉口int link[MAX];bool useif[MAX];bool dfs(int t){for(int i=1;i<=no_in;i++){if(!useif[i] && map[t][i]){useif[i]=true;if(link[i]==-1 || dfs(link[i])){link[i]=t;return true;}}}return false;}int match(){int sum=0;memset(link,-1,sizeof(link));for(int i=1;i<=no_in;i++){memset(useif,false,sizeof(useif));if(dfs(i))sum++;}return sum;}int main(){int T;int a,b;scanf("%d",&T);while(T--){memset(map,0,sizeof(map));scanf("%d%d",&no_in,&no_st);for(int i=1;i<=no_st;i++){scanf("%d%d",&a,&b);map[a][b]=1;//注意是單項路}printf("%d\n",no_in-match());}return 0;}
個人愚昧觀點...歡迎指正、交流討論

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.