竞赛图和哈密顿回路
競賽圖和哈密頓回路
結(jié)論
對于一個競賽圖,一定有哈密頓通路
對于一個強(qiáng)連通競賽圖,一定有哈密頓回路
競賽圖縮點后肯定是一條鏈
哈密頓通路證明
給出偽代碼
void work() {
int l = r = 1;
for (int i = 2;i <= n; i++) {
if (ed[i][l]) nxt[i] = l, l = i;
else if (ed[r][i]) nxt[r] = i, r = i;
else for (int j = l; ; j = nxt[j])
if (a[i][nxt[j]]) { nxt[i] = nxt[j], nxt[j] = i; break; }
}
}
我們維護(hù) 1 ~ i-1 的哈密頓路徑,考慮插入 i,如果可以接到頭尾直接加入即可。否則滿足有路徑 (l o i o r),考慮從中間找到滿足 (t o i o nxt[t]) 的位置然后把 i 插入即可,容易發(fā)現(xiàn)一定存在這樣一個位置。如果目前只有兩個點,顯然成立。如果不是,那么從 l 開始,滿足 (l o i),如果有 (i o nxt[l]) 直接滿足,否則滿足 (nxt[l] o i) 這樣還是原來的問題,這樣就可以用數(shù)學(xué)歸納法證了。
哈密頓回路證明
//這個部分最好畫圖理解,圖是一個環(huán)長一條尾巴的樣子。
r=0;//這里是緊接著上面找完通路。先把r置為0表示還沒有找到初始的環(huán)。
for(int i=l;i;i=nxt[i])//r是環(huán)上最靠近鏈的點,r->l是環(huán)上的邊,r->nxt[r]是鏈上的邊。
if(r){//嘗試在環(huán)中插入點i
for(int j=l,k=r;;k=j,j=nxt[j]){
if(a[i][j]){//在環(huán)上找到一個可以作為nxt[i]的點。
nxt[k]=nxt[r];//j作為了i的后繼,那么本來j的前驅(qū)k就要另找一個后繼了。(這里注意nxt[r]不一定是i,因為可能前面的一些點沒有插入成功)
if(k!=r)nxt[r]=l;//本來沒有連上的環(huán)上的邊要連上(k=r的話r的后繼在上一句話已經(jīng)改了,不是l了)
l=j,r=i;break;//根據(jù)l和r的定義修改l和r
}
if(j==r)break;//確實有可能當(dāng)前無法插入,但是后面的點一定會有插入成功的,那時這個點也就會進(jìn)入環(huán)內(nèi)。
}
}
else if(a[i][l])r=i;//這里找到了初始的環(huán)
nxt[r]=l;//這里把最后一條邊連上。
這個是學(xué)長的代碼,簡要說明一下
強(qiáng)連通的限制保證了不會有一個點向其他點都是正向邊或反向邊。
先找到一條哈密頓通路,容易發(fā)現(xiàn) $2 o n $ 中至少有一個點有連向 1 的邊,否則不會強(qiáng)連通,設(shè)它為 x,現(xiàn)在我們就有了一個 (1 o x o 1) 的哈密頓回路。現(xiàn)在考慮一個一個加入下一個點,考慮 (x+1) 的若干中情況。
有邊 (x + 1 o 1),讓 (x) 連 (x+1),(x+1) 連 1 即可
(x+1) 對所有的 (1 o x) 都有邊,將 (x+1) 和 (x+2) 這個線段看作整體,繼續(xù)考量 (x+2),這時候只要 (x+2) 對 (1 o x) 有反向邊就可以直接插入。由于強(qiáng)連通,所以不可能剩下的點都沒有反向邊。
否則一定存在 (t o x o nxt[t]),可以畫圖理解一下,和上面證哈密頓通路的過程是一樣的。
競賽圖縮點證明
假設(shè)縮點完畢,容易發(fā)現(xiàn)一個聯(lián)通分量到另一個連通分量肯定有限制關(guān)系,所以可以變成一條鏈。
總結(jié)
- 上一篇: 艾绒的制作(艾叶怎么加工成艾绒)
- 下一篇: easywechat (在thinkph