POJ 2513
阿新 • • 發佈:2018-04-11
最大 esp 而且 字典 JD 提醒 2個 oss ron
這道題在XZTdalao的諄諄教誨下,成功學會了trie
題意:有一些木棒,每一根木棒的兩端都只能染一種顏色。現在問你是否存在一種方案,將所有木棒排成一行,並滿足所有的染色要求(即相鄰的兩根木棒的公共交點顏色相同)
將題意抽象化,可以發現這是個歐拉回路的板子。將所有的木棒看做一條邊,顏色看成點。要滿足要求,就要使得到的圖有歐拉回路(顯然)。
而且這裏不需要輸出方案,所以就更加水了,直接記錄每個點的度數,找出奇點個數是否為0||2個。如果是那麽就是歐拉回路,反之。
但是,最大的問題來了:題目給出的方式是字符串,那麽就意味著還要對字符串進行處理。所以可以map或hash
但由於這道題數據範圍太大,因此map和hash掛鏈會T,寫雙(三)hash又很不舒服
這種情況下就可以使用字典樹——trie
關於trie的操作,先填個坑以後再補上。
這道題親測寫鄰接表可以A,但計算了一下最壞情況下鄰接矩陣會MLE
%CJJdalao直接用鄰接矩陣艹了過去
最後提醒一下,有解得首要條件還是圖要滿足聯通
並查集即可
CODE
#include<iostream> #include<string> #include<cstring> using namespace std; const int N=250005<<1; string s1,s2; struct edge { int to,next; }e[N*10]; struct node { char ch; int id; }trie[N*10]; int head[N*10],deg[N],father[N],k,cnt,tot,s; inline void add(int x,int y,char z) { e[y].to=y; trie[y].ch=z; e[y].next=head[x]; head[x]=y; } inline int insert(string s) { register int i,j; int now=0,len=s.size(); for (i=0;i<len;++i) { bool flag=0; for (j=head[now];j!=-1;j=e[j].next) if (trie[e[j].to].ch==s[i]) { now=e[j].to; flag=1; break; } if (!flag) add(now,++k,s[i]),now=k; if (i==len-1) { if (flag) return trie[now].id; else return trie[now].id=++cnt; } } } inline int getfather(int k) { return k==father[k]?k:father[k]=getfather(father[k]); } int main() { register int i; memset(head,-1,sizeof(head)); memset(e,-1,sizeof(e)); //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); for (i=1;i<N;++i) father[i]=i; while (cin>>s1>>s2) { int x=insert(s1),y=insert(s2); ++deg[x]; ++deg[y]; father[getfather(x)]=getfather(y); } for (s=getfather(1),i=2;i<=cnt;++i) if (s!=getfather(i)) { puts("Impossible"); return 0; } for (i=1;i<=cnt;++i) if (deg[i]%2) ++tot; if (tot==2||tot==0) puts("Possible"); else puts("Impossible"); return 0; }
POJ 2513