• poj 2513


    trie树+并查集,蛮好玩

      1 #include <iostream>
      2 #include <string>
      3 #include <vector>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <map>
      7 #include <algorithm>
      8 #include <list>
      9 #include <ctime>
     10 #include <set>
     11 #include <string.h>
     12 #include <queue>
     13 #include <cstdio>
     14 #define CLR(arr, what) memset(arr, what, sizeof(arr))
     15 typedef long long ll;
     16 const int MAX = 510000;
     17 using namespace std;
     18 
     19 const int branchNum = 26; //声明常量
     20 int colorct;
     21 int colorall[MAX];
     22 struct Trie_node {
     23     bool isStr; //记录此处是否构成一个串。
     24     Trie_node *next[branchNum]; //指向各个子树的指针,下标0-25代表26字符
     25     int colornum;
     26     Trie_node() :
     27             isStr(false) {
     28         colornum = 0;
     29         for (int i = 0; i < branchNum; i++)
     30             next[i] = NULL;
     31     }
     32 };
     33 
     34 class Trie {
     35 public:
     36     Trie();
     37     int insert(const char* word);
     38     bool search(char* word);
     39     void deleteTrie(Trie_node *root);
     40     bool pre_char(bool judge, Trie_node* top);
     41 public:
     42     Trie_node* root;
     43 };
     44 
     45 Trie::Trie() {
     46     root = new Trie_node();
     47 }
     48 
     49 int Trie::insert(const char* word) {
     50     Trie_node *location = root;
     51     while (*word) {
     52         if (location->next[*word - 'a'] == NULL) //不存在则建立
     53         {
     54             Trie_node *tmp = new Trie_node();
     55             location->next[*word - 'a'] = tmp;
     56         }
     57         location = location->next[*word - 'a']; //每插入一步,相当于有一个新串经过,指针要向下移动
     58         word++;
     59     }
     60     if (location->colornum == 0) {
     61         colorct++;
     62         location->colornum = colorct;
     63     }
     64     colorall[location->colornum]++;
     65     location->isStr = true; //到达尾部,标记一个串
     66     return location->colornum;
     67 }
     68 
     69 bool Trie::search(char *word) {
     70     Trie_node *location = root;
     71     while (*word && location) {
     72         location = location->next[*word - 'a'];
     73         word++;
     74     }
     75     return (location != NULL && location->isStr);
     76 }
     77 
     78 void Trie::deleteTrie(Trie_node *root) {
     79     int i;
     80     for (i = 0; i < branchNum; i++) {
     81         if (root->next[i] != NULL) {
     82             deleteTrie(root->next[i]);
     83         }
     84     }
     85     delete root;
     86 }
     87 
     88 bool Trie::pre_char(bool judge, Trie_node* top) {
     89     bool tmpjud, res;
     90     res = false;
     91     if (top->isStr && judge)
     92         return true;
     93     tmpjud = judge || top->isStr;
     94     for (int i = 0; i < branchNum; i++) {
     95         if (top->next[i] != NULL)
     96             res = res || pre_char(tmpjud, top->next[i]);
     97     }
     98     return res;
     99 }
    100 
    101 
    102 int father[MAX], num[MAX];
    103 
    104 void makeSet(int n)
    105 {
    106     int i;
    107     for(i = 0; i < n; i++)
    108     {
    109         father[i] = i; //使用本身做根
    110         num[i] = 1;
    111     }
    112 }
    113 int findSet(int x)
    114 {
    115     if(father[x] != x) //合并后的树的根是不变的
    116     {
    117         father[x] = findSet(father[x]);
    118     }
    119     return father[x];
    120 }
    121 
    122 void Union(int a, int b)
    123 {
    124     int x = findSet(a);
    125     int y = findSet(b);
    126     if(x == y)
    127     {
    128         return;
    129     }
    130     if(num[x] <= num[y])
    131     {
    132         father[x] = y;
    133         num[y] += num[x];
    134     }
    135     else
    136     {
    137         father[y] = x;
    138         num[x] += num[y];
    139     }
    140 }
    141 
    142 int main() {
    143     Trie t;
    144     makeSet(MAX);
    145     int ca,cb;
    146     char c1[11], c2[11];
    147     while (scanf("%s%s", c1, c2) != EOF) {
    148         ca=t.insert(c1);
    149         cb=t.insert(c2);
    150         Union(ca,cb);
    151     }
    152     if(colorct==0){
    153         cout<<"Possible\n";
    154         return 0;
    155     }
    156     int cnum=num[findSet(1)];
    157     if(cnum!=colorct){//判断连通性
    158         cout<<"Impossible\n";
    159                 return 0;
    160     }
    161     int ct=0;
    162     for(int i=0;i<colorct+1;i++){
    163         if(colorall[i]%2==1){
    164             ct++;
    165         }
    166         if(ct>2){
    167             break;
    168         }
    169     }
    170     if(ct==0||ct==2){
    171         cout<<"Possible\n";
    172     }else{
    173         cout<<("Impossible\n");
    174     }
    175     return 0;
    176 }

    from kakamilan

  • 相关阅读:
    P1182 数列分段`Section II`
    算法整理:Floyd_多源最短路
    【FBI WARNING】递归(高级数据结构的基础)
    【FBI WARNING】DP 从看透到看开
    两个例题
    结构体
    环状序列(Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)
    生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)
    猜数字游戏的提示(Master-Mind Hints, UVa 340)
    回文词(Palindromes, UVa401)
  • 原文地址:https://www.cnblogs.com/kakamilan/p/3110196.html
Copyright © 2020-2023  润新知