trie树+并查集+欧拉回路
用trie树将字符串一一映射(貌似用hash也行), 用并查集判断图是否联通,然后判断是否存在欧拉回路(不要以为回路不符合题意,其实只要拉直就好了),即度为奇数的点有两个或没有。
- #include <stdio.h>
- const int N = 250000 + 5;
- int fa[N*2]={0};
- int num;
- struct Node{
- Node *branch[26];
- int key;
- Node(){
- for ( int i=0; i<26; i++ )
- branch[i] = NULL;
- key = 0;
- }
- } *root;
- void NewNode( Node *point, int cnum )
- {
- Node *nnode = new Node();
- point->branch[cnum] = nnode;
- }
- int insert( char *word )
- {
- Node *point = root;
- while ( *word!='/0' )
- {
- int cnum = *word-'a';
- if ( point->branch[cnum] == NULL )
- NewNode( point , cnum );
- point = point->branch[cnum];
- word ++;
- }
- if ( point->key==0 )
- {
- point->key = ++num;
- fa[num-1] = num-1;
- }
- return point->key;
- }
- int v[N*2] = {0};
- int Root( int x)
- {
- int r = fa[x];
- if ( r!=x )
- fa[x] = Root( r );
- return fa[x];
- }
- int main ()
- {
- num = 0;
- root = new Node();
- int t1, t2;
- char s1[15], s2[15];
- while ( scanf("%s %s", s1, s2 )!=EOF )
- {
- t1 = insert( s1 );
- t2 = insert( s2 );
- int ra = Root( t1-1 );
- int rb = Root( t2-1 );
- if ( ra!=rb )
- fa[rb] = ra;
- v[t1-1]++;
- v[t2-1]++;
- }
- int nodd = 0;
- int rr = Root( 0 );
- int flag = 1;
- for ( int i=0; i<num; i++ )
- {
- if ( v[i]%2==1 )
- nodd ++;
- if ( Root(i)!=rr )
- {
- flag = 0;
- break;
- }
- }
- if ( ( nodd==0 || nodd==2 ) && flag )
- printf("Possible/n");
- else
- printf("Impossible/n");
- return 0;
- }