歐拉回路總結

歐拉回路讓我甚是苦惱, 估計是這兩天玩遊戲浮躁了自己, 在理解算法的時候就沒認真。 沒有完全理解就上戰場了, 結果各種RE+WA。下面是我對歐拉回路的理解。

1.基本概念: 歐拉道路 與 歐拉回路(區別在於一個‘回’字, 不再訴述, 自己搜索)

2.判斷方法: 圖是否連通(用並查集實現)+ 點的度數是否滿足條件(全爲偶數, 或只有兩個奇數)

3.輸出路徑: 用一個DFS壓棧, 然後從棧中輸出。(不甚理解, 如果你也是, 歡迎討論)

4.記錄邊關係:鄰接矩陣G[MAX_V][MAX_V]用來表示密集的邊edge關係, 無向圖中 矩陣G是對稱的, 要G[u][v]與G[v]   [u]同步更新。有向圖相反。 如果是稀疏的邊關係, 結點vertex又非常的多, 開一個G[MAX_V][MAX_V], 顯然是不合理的,用G[MAX_V]來表示,這個數組的元素是指針(實際是鏈表), 鏈表中的每一個結點, 指向與u有edge關係的vertex。

5.DFS中標記訪問: 經常是用一個vis[MAX_V][MAX_V]來表示, 同G矩陣很像。 但其實 有時候G可以這樣用: G[u][v]的數值表示u與v之 間路的條數(而非簡單的1, 表示存在關係), 每走過一遍, G[u][v]--; 當G[u][v]爲零時, 也就相當於vis[u][v] = VISTED;

6.歐拉回路的疑問: a.DFS搜索樹應該存在着走不通的路啊, 這樣的路難道不是非法的嗎? 就不用加判定條件嗎? 這個問題我至今似懂非懂。 最下面有兩個段代碼, 這一比較, 各種不理解。

7.題目:uva10596:簡單基礎題, 注意vertex數目小於2的情況。再有, 我WA + RE了好多次。

     uva10054:據說這題判回都不用, 只要判度數符合就行。 但我還是用並查集判回了, 結果在計算集合數目的時候, 把沒有的       點也考慮進來了。 如果不懂我說的意思, 你把題中樣例二 的 3 跟 4 分別用 7 8代替試試。

     uva10129:有向圖的歐拉道路存在性判斷。

8.還需要做的:

  a. DFS路徑這邊還是不理解, 需要再去理解。 這點很重要, 只有理解透徹了, 才能根據題目改造算法。

  b. 目前做過的題目基本比較水, 雖然我WA了很多遍, 但我相信這是自己狀態不好(小錯誤不斷)再加算法理解得不透徹引起      的。需要做些更深點題目 , 無向-》有向-》混合。 做些助於更好理解歐拉的題目。          


我看了別人的算法後寫的, 其中E是終點, 在main裏指定。

bool DFS(int root)
{
	if (countE == E && root == end) {		//訪問邊數等於總邊數 並且 現在的點爲終點時
		return true;
	}else if (countE == V && root != end) {
		return false;
	}

	for (int i = 0; i < V; i++) {
		if (G[root][i] && !vis[root][i])	{
			vis[root][i] = vis[i][root] = 1;
			countE++;
			if (DFS(i)) {					//如果遞歸下去能找到終點則打印, 否則回溯	
				printf("%d->", i);
				return true;
			}else {
				vis[i][root] = vis[root][i] = 0;
				countE--;
			}
		}
	}

	return false;							//當此點root(未到達終點)沒有其它點與之有關係 或 其它連接的邊已經走過時
}

這是劉汝佳書上的:

void euler(int u){
    for(int v=0; v<MAXN; ++v) if(G[u][v]){
        vis[u][v] = vis[v][u] = 1;
        euler(v);
        printf("%d %d\n", u,v);
    }
}

9. 後期心得: a.用DFS判斷連通:無論圖是有向無向, 都把圖當做無向。 這點很重要,不然DFS無法從任意點搜索起。

      b.在判斷點是否有過屬性改變前, 要先判斷, 這一點是否原本就有。 如果原本就有才有屬性改變可言, 否則何必去判斷呢?況且還可能會引起BUG 比如: 

//judge
bool okDFS() 
{
	for (int v = 0; v < MAX_V; v++) {
		if (vis[v] == UNVISTED) {
			return false;
		}
	}

	return true;
}
   for掃描所有的點(有的點是不存在的, 比如樣例只有a d f e這四個點其餘點都不存在),這時候你去判   斷vis屬性是否全變爲“已訪問” , 是不合理的。 當然啦 , vis一般會先全部清零。 但如果是別的屬   性呢?


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