這道題做的時候,幹的最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...