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

原文地址:https://www.cnblogs.com/kakamilan/p/3110196.html