PKU 2513 Colored Sticks

 trie树+并查集+欧拉回路

 

用trie树将字符串一一映射(貌似用hash也行), 用并查集判断图是否联通,然后判断是否存在欧拉回路(不要以为回路不符合题意,其实只要拉直就好了),即度为奇数的点有两个或没有。

 

  1. #include <stdio.h>
  2. const int N = 250000 + 5;
  3. int fa[N*2]={0};
  4. int num;
  5. struct Node{
  6.     Node *branch[26];
  7.     int key;
  8.     Node(){
  9.         for ( int i=0; i<26; i++ )
  10.             branch[i] = NULL;
  11.         key = 0;
  12.     }
  13. } *root;
  14. void NewNode( Node *point, int cnum )
  15. {
  16.     Node *nnode = new Node();
  17.     point->branch[cnum] = nnode;
  18. }
  19. int insert( char *word )
  20. {
  21.     Node *point = root;
  22.     while ( *word!='/0' )
  23.     {
  24.         int cnum = *word-'a';
  25.         if ( point->branch[cnum] == NULL  )
  26.             NewNode( point , cnum );
  27.         point = point->branch[cnum];
  28.         word ++;
  29.     }
  30.     if ( point->key==0 )
  31.     {
  32.         point->key = ++num;
  33.         fa[num-1] = num-1;
  34.     }
  35.     return point->key;
  36. }
  37. int v[N*2] = {0};
  38. int Root( int x)
  39. {
  40.     int r = fa[x];
  41.     if ( r!=x )
  42.         fa[x] = Root( r );
  43.     return fa[x];
  44. }
  45. int main ()
  46. {
  47.     num = 0;
  48.     root = new Node();
  49.     int t1, t2; 
  50.     char s1[15], s2[15];
  51.     while ( scanf("%s %s", s1, s2 )!=EOF )
  52.     {
  53.         t1 = insert( s1 );  
  54.         t2 = insert( s2 );
  55.         int ra = Root( t1-1 );
  56.         int rb = Root( t2-1 );
  57.         if ( ra!=rb )
  58.             fa[rb] = ra;
  59.         v[t1-1]++;
  60.         v[t2-1]++;
  61.     }
  62.     int nodd = 0;
  63.     int rr = Root( 0 );
  64.     int flag = 1;
  65.     for ( int i=0; i<num; i++ )
  66.     {
  67.         if ( v[i]%2==1 )
  68.             nodd ++;
  69.         if ( Root(i)!=rr )
  70.         {
  71.             flag = 0;
  72.             break;
  73.         }
  74.     }
  75.     if ( ( nodd==0 || nodd==2 ) && flag )
  76.         printf("Possible/n");
  77.     else
  78.         printf("Impossible/n");
  79.     return 0;
  80. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值