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吧~嘿嘿

    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    stm32之不定长接收
    3、列表和列表项
    2、FreeRTOS任务相关API函数
    1、FreeRTOS移植
    5、根文件系统原理
    1、c++对c语言的扩展
    4、移植三星官方内核
    3、内核的启动过程
    2、内核的配置和移植
    iOS学习笔记19-地图(一)定位CoreLocation
  • 原文地址:https://www.cnblogs.com/proverbs/p/2714459.html
Copyright © 2011-2022 走看看