日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

hihocder 1181 : 欧拉路·二

發(fā)布時(shí)間:2025/3/16 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hihocder 1181 : 欧拉路·二 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

因?yàn)橄噙B的兩個(gè)數(shù)字總是相同的,不妨我們只寫一次,那么這個(gè)例子可以寫成:3-2-4-3-5-1。6個(gè)數(shù)字剛好有5個(gè)間隙,每個(gè)間隙兩邊的數(shù)字由恰好對(duì)應(yīng)了一塊骨牌。

如果我們將每一個(gè)數(shù)字看作一個(gè)點(diǎn),每一塊骨牌看作一條邊。你覺得是怎么樣的呢?

小Ho:以這個(gè)例子來(lái)說(shuō)的話,就是:

要把所有的骨牌連起來(lái),也就是把所有的邊都走一次。咦,這不是歐拉路問(wèn)題么!

小Hi:沒錯(cuò),這問(wèn)題其實(shí)就是一個(gè)歐拉路的問(wèn)題,不過(guò)和上一次不一樣的在于,這一次我們要找出一條歐拉路徑。

小Ho:那我們應(yīng)該如何來(lái)找一條路徑呢?

小Hi:我們還是借用一下上次的例子吧

使用我們上一次證明歐拉路判定的方法,我們?cè)谶@個(gè)例子中找到了2條路徑:

L1: 4-5-2-3-6-5 L2: 2-4-1-2

假設(shè)我們棧S,記錄我們每一次查找路徑時(shí)的結(jié)點(diǎn)順序。當(dāng)我們找到L1時(shí),棧S內(nèi)的情況為:

S: 4 5 2 3 6 5 [Top]

此時(shí)我們一步一步出棧并將這些邊刪除。當(dāng)我們到節(jié)點(diǎn)2時(shí),我們發(fā)現(xiàn)節(jié)點(diǎn)2剛好是L1與L2的公共節(jié)點(diǎn)。并且L2滿足走過(guò)其他邊之后回到了節(jié)點(diǎn)2。如果我們?cè)谶@個(gè)地方將L2先走一遍,再繼續(xù)走L1不就剛好走過(guò)了所有邊么。

而且在上一次的證明中我們知道,除了L1之外,其他的路徑L2、L3...一定都滿足起點(diǎn)與終點(diǎn)為同一個(gè)點(diǎn)。所以從任意一個(gè)公共節(jié)點(diǎn)出發(fā)一定有一條路徑回到這個(gè)節(jié)點(diǎn)。

由此我們得到了一個(gè)算法:

  • 在原圖中找一個(gè)L1路徑

  • 從L1的終點(diǎn)往回回溯,依次將每個(gè)點(diǎn)出棧。并檢查當(dāng)前點(diǎn)是否還有其他沒有經(jīng)過(guò)的邊。若存在則以當(dāng)前點(diǎn)為起點(diǎn),查找L2,并對(duì)L2的節(jié)點(diǎn)同樣用棧記錄重復(fù)該算法。

  • 當(dāng)L1中的點(diǎn)全部出棧后,算法結(jié)束。

  • 在這里我們?cè)賮?lái)一個(gè)有3層的例子:

    在這個(gè)例子中:

    L1: 1-2-6-5-1 L2: 2-3-7-2 L3: 3-4-8-3

    第一步時(shí)我們將L1壓入棧S,同時(shí)我們用一個(gè)數(shù)組Path來(lái)記錄我們出棧的順序:

    S: [1 2 6 5 1] Path:

    然后出棧到節(jié)點(diǎn)2時(shí)我們發(fā)現(xiàn)了2有其他路徑,于是我們把2的另一條路徑加入:

    S: 1 [2 3 7 2] Path: 1 5 6

    此時(shí)L2已經(jīng)走完,然后再開始彈出元素,直到我們發(fā)現(xiàn)3有其他路徑,同樣壓入棧:

    S: 1 2 [3 4 8 3] Path: 1 5 6 2 7

    之后依次彈出剩下的元素:

    S: Path: 1 5 6 2 7 3 8 4 3 2 1

    此時(shí)的Path就正好是我們需要的歐拉路徑。

    小Ho:原來(lái)這樣就能求出歐拉路,真是挺巧妙的。

    小Hi:而且這個(gè)算法在實(shí)現(xiàn)時(shí)也有很巧妙的方法。因?yàn)镈FS本身就是一個(gè)入棧出棧的過(guò)程,所以我們直接利用DFS的性質(zhì)來(lái)實(shí)現(xiàn)棧,其偽代碼如下:

    DFS(u):While (u存在未被刪除的邊e(u,v))刪除邊e(u,v)DFS(v)EndPathSize ← PathSize + 1

    Path[ PathSize ] ← u

    要注意,在DFS的時(shí)候,如果歐拉圖當(dāng)中存在奇數(shù)度的頂點(diǎn),那么一定要從該頂點(diǎn)出發(fā),如果沒有,則任一點(diǎn)都行。。。。

    #include<iostream> #include<cstdio> #include<cstring> using namespace std;int n,m,edge[1001][1001],degree[1001]; int path[1001],len;void dfs(int u) {for(int i = 1; i <= n; i++){if(edge[u][i] > 0){edge[u][i]--, edge[i][u]--;dfs(i);}}path[len++] = u; }int main() { while(scanf("%d%d",&n,&m)!=EOF){int u,v;memset(edge,0,sizeof(edge));memset(degree,0,sizeof(degree));for(int i = 1; i <= m; i++){scanf("%d%d",&u,&v);edge[u][v]++, edge[v][u]++;degree[u]++, degree[v]++;}int k = 1;for(int i = 1; i <= n; i++){if(degree[i] % 2 == 1){k = i;break;}}len = 0;dfs(k);for(int i = len-1; i >= 0; i--)printf("%d ",path[i]);printf("\n");}return 0; }

    總結(jié)

    以上是生活随笔為你收集整理的hihocder 1181 : 欧拉路·二的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。