POJ 2513 Trie樹 並查集以及尤拉路徑

2021-08-24 20:45:52 字數 3258 閱讀 2510

這道題做的時候,幹的最sb的事就是斷點列印的東西沒刪乾淨,結果導致一開始怎麼交怎麼wa,後來怎麼交怎麼ac。不過仍然有很困惑的地方,就是在csdn blog中,他的trie樹第二維只有15,但是能過,就很奇怪,而且將其改到應該是正確的26,卻runtime error。

主要是三個方面,trie樹、並查集和尤拉迴路/路徑。並查集用於檢查是否為連通圖,不是必須的,但是可以減少2/3的執行時間,用dfs也可以做,但是不能使用std::vector前向星來儲存圖,太慢了,應該用鍊錶式的前向星。

trie樹的作用是判斷輸入的顏色是否已經出現過,一開始用hash做,以為hash雜湊開來就不會用太多時間,事實證明是不行的。trie樹還可以用來根據單詞字首尋找單詞或者統計,稍作修改即可。一開始一直使用參考的trie樹,直接開乙個二維陣列儲存,也不知道為什麼他用15都能過,26可能是因為開的陣列太大。

/* trie-tree using 2d array */

struct trie

int index(char ch)

void insert(char ch)

has_color[root] = ++color_cnt;

}int find(char ch)

return has_color[root];

}int find_or_insert(char ch)

if (!has_color[root])

has_color[root] = ++color_cnt;

return has_color[root];}};

這樣的儲存方式,其實也是按需分配,但可能實際並沒有這麼多的節點,所以超記憶體了,參考另一篇部落格,使用樹狀儲存則沒有問題,**見下。

/* trie-tree using linked tree */

struct trienode

};struct trie

int index(char ch)

int find_or_insert(char ch)

if (!cur->is_color)

return cur->color_id;}};

並查集(union & find)用於判斷圖的連通性,其通過建立樹狀結構來組織不同的集合,當我們想要判斷兩個節點是否在同一集合中,只要查詢這兩個節點的根節點是否為同乙個就行了。我們先定義find操作,通過遞迴查詢找到當前節點的根節點。

int

parent[n];

void init()

int find(int u)

比如我們現在有五個節點0 1 2 3 4,假設有union操作如下,經過union(0, 1); union(1, 2); union(3, 4)之後的樹狀結構應該是下圖,對應陣列1 2 2 4 4。

此時進行union(1, 3),則陣列會變成1 4 2 4 4,如下圖

這樣的連通性顯然是不對的,因此union操作應該將兩樹的根節點接在一起,才能讓這兩個集合連通,對應陣列1 2 4 4 4

當然如果每次都沿著整個樹查詢,將會是非常低效的,因此我們在沿樹查詢的過程中,將一顆子樹中所有的節點的父節點都指向根節點

int find(int u)

上文的union(1, 3)不能體現這個效果,所以我們換成union(0, 3),執行find(0)後如下圖,對應陣列2 2 2 4 4

執行find(3)之後樹不變,整個函式執行完後如下圖,對應陣列2 2 4 4 4

這個時候如果執行一遍find(0),則重排會變成4 3 4 4 4,對應下圖

解決了連通性的問題,那麼要判斷尤拉迴路/路徑,則非常簡單,只要統計一下度數為奇數的節點個數就行了,如果為0或者2,則構成尤拉迴路或路徑。

#include 

#include

const

int n = 500005;

int color_cnt = 0;

struct trienode

};struct trie

int index(char ch)

int find_or_insert(char ch)

if (!cur->is_color)

return cur->color_id;

}};int degree[n] = ;

int origin[n];

int find_origin(int u)

void connect(int u, int v)

int main()

bool is_connected = true;

int source = -1;

for (int i = 1; is_connected && i <= color_cnt; ++i)

int degree_cnt = 0;

for (int i = 1; i <= color_cnt; ++i)

if (degree_cnt <= 2 && is_connected)

printf("possible\n");

else

printf("impossible\n");

}

POJ 2513 Trie樹 尤拉迴路 並查集

1.把木棒的端點考慮為頂點,木棒考慮為邊,建立起乙個無向圖。2.問題轉化為在無向圖上判斷是否有尤拉迴路或者尤拉道路。3.在無向圖上判斷是否有尤拉迴路或者尤拉道路 尤拉定理 並查集 判斷連通性 4.考慮如何統計每個頂點的度,開始用的是暴力解法,直接用陣列記錄頂點,並且通過順序查詢獲得頂點編號,tle,...

POJ 2513 TRIE樹 並查集 尤拉路

題意 給定許多根木棒,兩邊分別塗有不同顏色,問能否將他們連成一條直線。規定只能將相同顏色的兩端相連。思路 用trie樹儲存單詞,trie樹最後乙個字母的節點編號就是這個單詞的編號 可以和模擬 並查集檢查是否連通 有尤拉路的前提是圖連通 最後加上無向圖尤拉路的判定就好了 奇數度的節點只能有0或2個 v...

POJ 2513(trie 並查集 尤拉迴路)

自認為此題有個bug define number 500005 int p number 5 int rank number 5 void make set int x int find set int x void link set int x,int y void union set int x...