zoukankan      html  css  js  c++  java
  • poj 2513 并查集,Trie(字典树), 欧拉路径

    You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

    Input

    Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.

    Output

    If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.

    Sample Input

    blue red
    red violet
    cyan blue
    blue magenta
    magenta cyan
    

    Sample Output

    Possible

    Hint

    Huge input,scanf is recommended.
     
    给你若干木棒和木棒两端的颜色,要你判断能否将这些木棒连成一条线,要求接触的两端颜色需要相同。
    木棒个数不超过25万,那么颜色最多可以达到50万。这种类型的题是欧拉路径的经典题目, 需要判断是否为连接图,由于几十万的数据,一开始用的是bfs,超时。后来看了discuss用了并查集,跑了1.3s左右,是最快的三倍。然而可以过。。。。注意HINT,建议用scanf,说明用cin容易超时(事实上我也用string试过,果然超时。。),由于颜色使用字符串表示,而string和cin又太慢,这个时候就需要用到字典树了,关于字典树,欧拉路径, 并查集可以在网上查找资料。
    上代码
      1 #include <cstring>
      2 #include <cstdio>
      3 #include <iostream>
      4 #define maxn 500000 + 10
      5 using namespace std;
      6 char str[maxn][12];
      7 int sum = 0;
      8 struct Node
      9 {
     10     int ID;
     11     Node *next[27];
     12     Node()
     13     {
     14         ID = -1;
     15         for(int i = 0; i < 27; i++)
     16         {
     17             next[i] = NULL;
     18         }
     19     }
     20 };
     21 Node *newnode(){return new Node;}
     22 Node *root = newnode();
     23 int getID(char *s)
     24 {
     25     Node *u = root;
     26     int len = strlen(s);
     27     for(int i = 0; i < len; i++)
     28     {
     29         int x = s[i] - 'a';
     30         if(u->next[x] == NULL)
     31             u->next[x] = newnode();
     32         u = u->next[x];
     33     }
     34     if(u->ID == -1)
     35     {
     36         return u->ID = sum++;
     37     }
     38     return u->ID;
     39 }
     40 ///并查集
     41 int fat[maxn];
     42 int R[maxn];
     43 int gettop(int a)
     44 {
     45     if(fat[a] != a)
     46     {
     47         fat[a] = gettop(fat[a]);
     48         //printf("top[%d] = %d
    ", a, fat[a]);
     49     }
     50     else return a;
     51 }
     52 void Link(int a, int b)
     53 {
     54     int x = gettop(a);
     55     int y = gettop(b);
     56     if(a == b) return;
     57     if(R[a] < R[b])
     58     {
     59         fat[a] = fat[b];
     60     }
     61     else
     62     {
     63         fat[b] = fat[a];
     64         if(R[a] == R[b])
     65             R[a]++;
     66     }
     67 
     68 }
     69 int num[maxn];
     70 int main()
     71 {
     72     for(int i = 0; i < maxn; i++)
     73     {
     74         fat[i] = i;
     75         memset(str[i], 0, sizeof(str[i]));
     76     }
     77     memset(R, 0, sizeof(R));
     78     memset(num, 0, sizeof(num));
     79     char s[12], t[12];
     80 
     81     while(scanf("%s%s", &s, &t) != EOF)
     82     {
     83         int a = getID(s);
     84         int b = getID(t);
     85         int l1 = strlen(s);
     86         int l2 = strlen(t);
     87         if(str[a][0] != 0)
     88         {
     89             for(int i = 0; i < l1; i++)
     90                 str[a][i] = s[i];
     91             str[a][l1] = 0;
     92         }
     93         if(str[b][0] != 0)
     94         {
     95             for(int i = 0; i < l2; i++)
     96                 str[b][i] = t[i];
     97             str[b][l2] = 0;
     98         }
     99         num[a]++;
    100         num[b]++;
    101         Link(a, b);
    102         //printf("fat[%d]=%d, fat[%d]=%d
    ", a, fat[a], b, fat[b]);
    103     }
    104     int ok = 1;
    105     int Top = fat[0];
    106     for(int i = 0; i < sum; i++)
    107     {
    108        // printf("top[%d] = %d
    ", i, gettop(i));
    109         gettop(i);
    110         if(fat[i] != Top)
    111         {
    112 
    113             ok = 0;
    114             break;
    115         }
    116     }
    117     if(ok)
    118     {
    119        // printf("Wrong is here
    ");
    120         int NUM = 0;
    121         for(int i = 0; i < sum; i++)
    122         {
    123             if(num[i] % 2) NUM++;
    124         }
    125         if(NUM > 2) ok = 0;
    126     }
    127     if(ok) printf("Possible
    ");
    128     else printf("Impossible
    ");
    129     return 0;
    130 }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    print “ 欢迎来到渣小狼的博客,这既是博客,也是日记,里面记录了小狼的学习经历还有一些小狼的见解,非常希望每一个来到这里的人能够留下只言片语,更加的希望留下的是对于小狼的不足的补充,谢谢(*^__^*) 嘻嘻……”
  • 相关阅读:
    socket
    RBAC
    CMOS和BIOS
    canvas和SVG
    兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面
    HTML标签marquee实现滚动效果
    百度判断手机终端并自动跳转uaredirect.js代码及使用实例
    JavaScript中常用的事件
    解决windows server 2008 r2 登录进入桌面只显示一片蓝色背景
    ng2自定义管道
  • 原文地址:https://www.cnblogs.com/wolf-yasen/p/6759225.html
Copyright © 2011-2022 走看看