这题综合性蛮强,数据结构使用到了并查集+trie树,理论用到了欧拉回路。
颜色为图中的节点,棍子为边。并查集的元素是数字,要把颜色string隐射到数字,
用STL的map进行索引竟然超时。 那于是就用trie树吧。
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <list>
#include <set>
#include <time.h>
#include <string.h>
#include <string>
#include <iostream>
#include <map>
using namespace std;
int id = 0;
int father[500010];
int Rank[500010];
int delta[500010];
char word1[20];
char word2[20];
struct TreeNode{
int exist;
int index;
TreeNode *next[26];
TreeNode():exist(0),index(-1){
memset(next,0,sizeof(next));
}
};
TreeNode *root = new TreeNode();
void insert(char *word){
TreeNode *loc = root;
while(*word != '\0'){
if(!loc->next[*word - 'a'])
loc->next[*word-'a'] = new TreeNode();
loc = loc->next[*word - 'a'];
++word;
}
if(loc->exist==0){
loc->exist = 1;
loc->index = id++;
}
}
int get_index(char *word){
TreeNode *loc = root;
while(*word != '\0'){
loc = loc->next[*word-'a'];
++word;
}
return loc->index;
}
void make_set(int x){
father[x] = x;
Rank[x] = 0;
}
int find_set(int x){
if(father[x]!=x){
father[x] = find_set(father[x]);
}
return father[x];
}
void union_set(int i, int j){
int x = find_set(i);
int y = find_set(j);
if(x==y)
return;
if(Rank[x]>Rank[y])
father[y] = x;
else{
father[x] = y;
if(Rank[x]==Rank[y])
++Rank[y];
}
}
void process(){
int count = 0;
for(int i=0;i<id;++i)
if(delta[i]%2==1)
++count;
if(count!=0 && count!=2){
printf("Impossible\n");
return;
}
for(int i=1;i<id;++i)
if(find_set(i)!=find_set(i-1)){
printf("Impossible\n");
return;
}
printf("Possible\n");
}
int main(){
for(int i=0;i<500000;++i)
make_set(i);
int x,y;
while(scanf("%s %s",word1,word2)!=EOF){
insert(word1);
insert(word2);
x = get_index(word1);
y = get_index(word2);
++delta[x];
++delta[y];
union_set(x,y);
}
process();
//system("pause");
return 0;
}