• POJ2513 Colored Sticks


      原题传送:http://poj.org/problem?id=2513

      字典树 + 并查集 + 欧拉路。

      字典树:相当于hash的功能

      并查集:判断连通

      欧拉路:求答案

      要存在欧拉路就要满足:

      1.该图必须是一个连通图

      2.该图每个点的度数要么全为偶数,要么有且仅有两个点的度数为奇数

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <queue>
     4 #define N 500005
     5 using namespace std;
     6 
     7 int k, f[N],g[N];
     8 char a[15], b[15];
     9 
    10 struct trie
    11 {
    12     int id;
    13     trie *next[26];
    14     trie()
    15     {
    16         id = 0;
    17         memset(next, 0, sizeof next);
    18     }
    19 };
    20 
    21 int insert(trie *root, char s[])
    22 {
    23     trie *cur = root;
    24     for(int i = 0; s[i]; i ++)
    25     {
    26         int m = s[i] - 'a';
    27         if(cur->next[m] == NULL)
    28         {
    29             cur->next[m] = new trie();
    30         }
    31         cur = cur->next[m];
    32     }
    33     if(cur->id == 0)
    34         cur->id = k ++;
    35     return cur->id;
    36 }
    37 
    38 int find(int x)
    39 {
    40     return f[x] == x ? f[x] : f[x] = find(f[x]);
    41 }
    42 
    43 void union_set(int x, int y)
    44 {
    45     int u = find(x);
    46     int v = find(y);
    47     f[v] = u;
    48 }
    49 
    50 void init()
    51 {
    52      k = 1;
    53      for(int i = 1; i < N; i ++)
    54         f[i] = i;
    55 }
    56 
    57 int main()
    58 {
    59     int i;
    60     trie *root = new trie();
    61     init();
    62     while(scanf("%s%s", a, b) != EOF)
    63     {
    64         int x = insert(root, a);
    65         int y = insert(root, b);
    66         union_set(x, y);
    67         g[x] ++, g[y] ++;
    68     } 
    69     int v = find(1);
    70     for(i = 2; i < k; i ++)
    71     {
    72         if(find(i) != v)
    73             break;
    74     }
    75     if(i < k)
    76         puts("Impossible");
    77     else
    78     {
    79         int cnt = 0;
    80         for(i = 1; i < k ; i ++)
    81         {
    82             if(g[i] & 1)
    83                 cnt ++;
    84         }
    85         if(cnt == 0 || cnt == 2)
    86             puts("Possible");
    87         else   
    88             puts("Impossible");
    89     }
    90     return 0;
    91 }

      程序跑了1300+ms,对于5000ms的时限来说还是合理的。

      如果追求更快,那么搞IO加速、循环跳出或静态字典树都能省不少时间,但总体思路还是一样的。

  • 相关阅读:
    UIActivityIndicatorView的使用
    几道面试题-考察JS的运用
    第六章-面向对象的程序设计(理解对象)
    webpack学习之——npm的安装依赖情况
    面向对象的编程(五)
    Javascript面向对象编程(四):非构造函数的继承
    面向对象的编程(三)—封装
    面向对象的编程(二)构造函数的继承
    面向对象的编程—封装
    第五章——引用类型
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/2723938.html
Copyright © 2020-2023  润新知