zoukankan      html  css  js  c++  java
  • 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吧~嘿嘿

    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    HTML元素解释
    Java命名规范
    HDU 1058 Humble Numbers(DP,数)
    HDU 2845 Beans(DP,最大不连续和)
    HDU 2830 Matrix Swapping II (DP,最大全1矩阵)
    HDU 2870 Largest Submatrix(DP)
    HDU 1421 搬寝室(DP)
    HDU 2844 Coins (组合背包)
    HDU 2577 How to Type(模拟)
    HDU 2159 FATE(二维完全背包)
  • 原文地址:https://www.cnblogs.com/proverbs/p/2714459.html
Copyright © 2011-2022 走看看