题意:给出很多很多很多很多个棒子 左右各有颜色(给出的是单词) 相同颜色的可以接在一起,问是否存在一种
方法可以使得所以棒子连在一起
思路:就是一个判欧拉通路的题目,欧拉通路存在:没奇度顶点 或者只有2个奇度顶点 同时要连通 。关键在于给颜色hash和
判断连通性 hash用字典树 连通用并查集
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 const int maxn=520000+20; 6 struct Trie{ 7 int ch[maxn][26]; 8 int size; 9 int num[maxn]; 10 int number; 11 void init(){ 12 memset(ch,0,sizeof(ch)); 13 size=1; 14 number=1; 15 memset(num,0,sizeof(num)); 16 } 17 void insert(char*s){ 18 int rc=0,i=0; 19 for(;s[i]!='\0';i++){ 20 int id=s[i]-'a'; 21 if(ch[rc][id]==0){ 22 ch[rc][id]=size++; 23 } 24 rc=ch[rc][id]; 25 } 26 if(num[rc]==0)num[rc]=number++; 27 } 28 int find(char*s){ 29 int rc=0,i=0; 30 for(;s[i]!='\0';i++){ 31 int id=s[i]-'a'; 32 if(ch[rc][id]==0){ 33 return -1; 34 } 35 // if(s[i+1]=='\0')return ch[rc][id]; 36 rc=ch[rc][id]; 37 } 38 return num[rc]; 39 } 40 }trie; 41 int father[maxn]; 42 int Find(int x){ 43 return father[x]=father[x]==x?x:Find(father[x]); 44 } 45 void merge(int x,int y){ 46 x=Find(x); 47 y=Find(y); 48 if(x!=y) 49 father[x]=y; 50 } 51 char s1[1000],s2[1000]; 52 int dgree[maxn]; 53 int main(){ 54 trie.init(); 55 int flag=0; 56 for(int i=0;i<=maxn;i++)father[i]=i; 57 int maxnum=0; 58 while(scanf("%s%s",s1,s2)==2){ 59 trie.insert(s1);trie.insert(s2); 60 int x=trie.find(s1); 61 int y=trie.find(s2); 62 dgree[x]++; 63 dgree[y]++; 64 maxnum=max(maxnum,x); 65 maxnum=max(maxnum,y); 66 merge(x,y); 67 } 68 int z=0; 69 for(int i=1;i<=maxnum;i++){ 70 if(dgree[i]%2)z++; 71 } 72 flag=Find(1); 73 int ok=1; 74 for(int i=1;i<=maxnum;i++){ 75 if(flag!=Find(i)){ 76 // cout<<i<<" "<<Find(i)<<" "<<flag<<endl; 77 ok=0;break; 78 } 79 } 80 // cout<<ok<<" "<<z<<endl; 81 if((ok)&&(z==2||z==0))printf("Possible\n"); 82 else printf("Impossible"); 83 84 return 0; 85 }