zoukankan      html  css  js  c++  java
  • POJ 2513 Colored Sticks 字典树 + 并查集 + 欧拉通路

    比赛那天下午做的。。。比赛的时候真不知道怎么做。。。亏了没做,做了我就死了。。欧拉回路我是真心不会判断啊(真的是忘了)。。。虽然离散考了86(鼓掌~),也不过是全班最高(再次鼓掌~)但是真的是恶补出来的(天赋秉异,美女上台献花)

    不扯淡了。。。这道题因为数据量比较大。。。500000的数据,所以用map和平常的查找肯定会TLE所以,要用到TRIE树。

    然后欧拉通路的判定就是通过查找度数为奇数的节点  < 2 是否成立不成立肯定是错的,但是成立了也要判断是不是父节点是否为一个节点。比如

    red red

    blue blue

    答案就是impossible

    代码如下

    View Code
      1 #include <stdio.h>
      2 #include <string.h>
      3 struct node
      4 {
      5     int count;
      6     int next[27];
      7 }word[250050*4];
      8 int num = -1;
      9 int count = 0;
     10 int set[500050];
     11 int b[500050];
     12 
     13 void new_node()//新建节点
     14 {
     15     num++;
     16     word[num].count = 0;
     17     for(int i = 0;i < 27;i++)
     18     word[num].next[i] = -1;
     19 
     20 }
     21 int insert(char *s,struct node word[])
     22 {
     23     int i,dic;
     24     for(i = 0,dic = 0;s[i] != '\0';i++)
     25     {
     26         if(word[dic].next[s[i]-'a'] == -1)
     27         {
     28             new_node();
     29             word[dic].next[s[i]-'a'] = num;
     30         }
     31         dic = word[dic].next[s[i]-'a'];
     32 
     33     }
     34     word[dic].count++;
     35     if(word[dic].count == 1)
     36     b[count++] = dic;
     37 
     38 
     39     return dic;
     40 }
     41 int find(int i)//此处最好用这种递归
     42 {
     43     if(set[i] != i)
     44     set[i] = find(set[i]);
     45     return set[i];
     46 }
     47 void merge(int x,int y)
     48 {
     49     int fx = find(x);
     50     int fy = find(y);
     51     if(x != y)
     52     {
     53         set[fx] = fy;
     54     }
     55 }
     56 int main()
     57 {
     58    
     59     char s1[20],s2[20];
     60 
     61     int i;
     62     for(i = 0;i < 510005;i++)
     63     set[i] = i;
     64     new_node();
     65     while(~scanf("%s %s",s1,s2))
     66     {
     67         int x1,x2;
     68         x1 = insert(s1,word);
     69         x2 = insert(s2,word);
     70         merge(x1,x2);
     71 
     72 
     73     }
     74     int leap = 0,tag = 1;
     75     for(i = 0;i < count;i++)
     76     {
     77         if(word[b[i]].count%2)//度数为奇的节点数是否小于2
     78         leap++;
     79         if(leap > 2)
     80         {
     81             tag = 0;
     82             break;
     83 
     84         }
     85     }
     86     if(tag)
     87     {
     88         int par;
     89         par = find(set[b[0]]);
     90         for(i = 0;i < count;i++)
     91         {
     92             int temp = find(set[b[i]]);//一定要超找一下,千万不要直接用set[b[i]]
     93             if(temp != par)
     94             {
     95                 tag = 0;
     96                 break;
     97             }
     98 
     99         }
    100     }
    101     if(tag)
    102     puts("Possible");
    103     else
    104     puts("Impossible");
    105 
    106     return 0;
    107 }
  • 相关阅读:
    JS 日期加多少天,减多少天
    SQL 触发器
    SGU100
    连续子数组的最大和
    字符串的排列
    二叉搜索树与双向链表
    数组中出现次数超过一半的数字
    复杂链表的复制
    二叉树中和为某一值的路径
    二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/0803yijia/p/2649670.html
Copyright © 2011-2022 走看看