1.把木棒的端點考慮為頂點,木棒考慮為邊,建立起乙個無向圖。
2.問題轉化為在無向圖上判斷是否有尤拉迴路或者尤拉道路。
3.在無向圖上判斷是否有尤拉迴路或者尤拉道路:尤拉定理+並查集(判斷連通性)
4.考慮如何統計每個頂點的度,開始用的是暴力解法,直接用陣列記錄頂點,並且通過順序查詢獲得頂點編號,tle,然後考慮用map(紅黑樹),每次以logn的時間複雜度完成頂點度的 更新,繼續tle,想到用hash,不過沒想到好的對映方式,最後搜解題報告,發現trie樹這種玩意。
6.trie樹能以o(sizeof(key))的時間複雜度完成字串的查詢,所以每次更新頂點度的時間複雜度可以優化為o(1),這樣應該不會超時。
7.trick:在沒有任何木條時,應該輸出possible.
8.靜態實現trie比動態實現trie更快。
9.實現**(動態+遞迴):
#include
#include
#include
using namespace std;
const int maxn = 500001;
int p[maxn],maxv=0,deg[maxn];
void init()
int site = key[cur]-'a';
if((*curr).next[site]==null)
//沒找到
return find(key,cur+1,(*curr).next[site],len);
}void insert(char *key,int cur,node *curr,int len)
int site = key[cur]-'a';
if((*curr).next[site]==null)
insert(key,cur+1,(*curr).next[site],len);}};
int main()
else deg[u]++;
v = tree.find(s,0,tree.root,strlen(s));
if(v==-1)
else deg[v]++;
merge(u,v);
}maxv = tree.wordnum;
if(maxv==0)
bool ok = euler()&&conn();
if(ok) printf("possible\n");
else printf("impossible\n");
return 0;
}
10.靜態實現+迭代,**:
#include
#include
#include
using namespace std;
struct trie_node
}trie[700000];
const int maxn = 500002;
int p[maxn],deg[maxn],maxv=0,triem=2;
void init()
int find(int x)
void merge(int x,int y)
int insert(char *word)
//如果沒有該元素
if(trie[ptr].id==-1)
return trie[ptr].id;
}bool conn()
bool euler()
return cnt==0||cnt==2;
}int main()
if(maxv==0)puts("possible");
else
return 0;
}
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...
POJ 2513 TRIE樹 並查集 尤拉路
題意 給定許多根木棒,兩邊分別塗有不同顏色,問能否將他們連成一條直線。規定只能將相同顏色的兩端相連。思路 用trie樹儲存單詞,trie樹最後乙個字母的節點編號就是這個單詞的編號 可以和模擬 並查集檢查是否連通 有尤拉路的前提是圖連通 最後加上無向圖尤拉路的判定就好了 奇數度的節點只能有0或2個 v...
POJ 2513 Trie樹 並查集以及尤拉路徑
這道題做的時候,幹的最sb的事就是斷點列印的東西沒刪乾淨,結果導致一開始怎麼交怎麼wa,後來怎麼交怎麼ac。不過仍然有很困惑的地方,就是在csdn blog中,他的trie樹第二維只有15,但是能過,就很奇怪,而且將其改到應該是正確的26,卻runtime error。主要是三個方面,trie樹 並...