POJ 2513 TRIE树+并查集+欧拉路

题意:

给定许多根木棒,两边分别涂有不同颜色,问能否将他们连成一条直线。规定只能将相同颜色的两端相连。

思路:

用TRIE树储存单词,TRIE树最后一个字母的节点编号就是这个单词的编号(可以和<map>类比)

并查集检查是否连通——有欧拉路的前提是图连通

最后加上无向图欧拉路的判定就好了~奇数度的节点只能有0或2个

 

View Code
  1 #include <cstdio>

  2 #include <cstring>

  3 #include <cstdlib>

  4 #include <string>

  5 #include <iostream>

  6 

  7 #define N 300000

  8 #define BUG system("pause")

  9 

 10 using namespace std;

 11 

 12 struct TRIE

 13 {

 14     bool bot;

 15     int son[28];

 16 }trie[N*5];

 17 

 18 char sa[N][12],sb[N][12];

 19 int num,cnt,now,wd[N*8],bh[N][2],fa[N*8];

 20 bool fg[N*8];

 21 

 22 void init()

 23 {

 24     for(int i=0;i<26;i++) trie[0].son[i]=-1;

 25     num=0;

 26 }

 27 

 28 void insert(char a[])

 29 {

 30     now=0;

 31     int len=strlen(a+1);

 32     for(int i=1;i<=len;i++)

 33     {

 34         if(trie[now].son[a[i]-'a']==-1)

 35         {

 36             num++;

 37             for(int j=0;j<26;j++) trie[num].son[j]=-1;

 38             trie[num].bot=false;

 39             trie[now].son[a[i]-'a']=num;

 40         }

 41         now=trie[now].son[a[i]-'a'];

 42     }

 43     trie[now].bot=true;

 44     wd[now]++;//单词出现次数 

 45     fg[now]=true;

 46 }

 47 

 48 int findfa(int x)

 49 {

 50     if(x!=fa[x]) fa[x]=findfa(fa[x]);

 51     return fa[x];

 52 }

 53 

 54 bool judge()

 55 {

 56     int cs=0,cf=0;

 57     memset(fg,0,sizeof fg);

 58     for(int i=1;i<=cnt;i++)

 59     {

 60         if((wd[bh[i][0]]&1)&&!fg[bh[i][0]]) cs++,fg[bh[i][0]]=true;

 61         if((wd[bh[i][1]]&1)&&!fg[bh[i][1]]) cs++,fg[bh[i][0]]=true;

 62     }

 63     memset(fg,0,sizeof fg);

 64     

 65     if(cs==1||cs>2) return false;

 66     

 67     for(int i=1;i<=num;i++) fa[i]=i; 

 68     

 69     for(int i=1;i<=cnt;i++)

 70     {

 71         fg[bh[i][0]]=fg[bh[i][1]]=true;

 72         if(findfa(bh[i][0])!=findfa(bh[i][1]))

 73             fa[findfa(bh[i][0])]=findfa(bh[i][1]);

 74     }

 75     for(int i=1;i<=num;i++)

 76         if(fg[i])

 77         {

 78             if(cf==0) cf=findfa(i);

 79             else if(cf!=findfa(i)) return false;

 80         }

 81         

 82     return true;

 83 }

 84 

 85 void go()

 86 {

 87     if(judge()) puts("Possible");

 88     else puts("Impossible");

 89 }

 90 

 91 void read()

 92 {

 93     cnt=1;

 94     while(scanf("%s%s",sa[cnt]+1,sb[cnt]+1)!=EOF)

 95     {

 96         insert(sa[cnt]);   bh[cnt][0]=now;

 97         insert(sb[cnt]);   bh[cnt][1]=now;

 98         cnt++;

 99     }

100     cnt--;

101 }

102 

103 int main()

104 {

105     init();

106     read();

107     go();

108     return 0;

109 }

 

好久不写trie了,因为数组开小了WA了两次,也勉强给自己一个1A吧~嘿嘿

你可能感兴趣的:(trie)