zoukankan      html  css  js  c++  java
  • POJ2513 【并查集+欧拉路径+trie树】

    题目链接:http://poj.org/problem?id=2513

    Colored Sticks

    Time Limit: 5000MS   Memory Limit: 128000K
    Total Submissions:40949   Accepted: 10611

    Description

    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.
     
    题目大意:给出以下字符串,代表每根棍子的两端颜色,只能将颜色相同的端点连接起来。问是否能连成一欧拉路径。
    思路:
    1.棍子两端无方向要求,故是无向图的欧拉路径,无向图判断欧拉路径的充要条件是:图连通(无向图的连通性可以用并查集来判断,但有向图不可以)+ 点的度全为偶/当且仅当只有2个点的度为奇
    2.关键在于将颜色字符串映射成整型编号,有两种思路:用map直接映射(TLE),用trie树给字符串上编号。
    3.具体实现在代码中,值得注意的一点是 G++才能AC。
     1 #include<stdio.h>
     2 #include<string.h>
     3 #define mem(a, b) memset(a, b, sizeof(a))
     4 const int MAXN = 250000 * 2 + 10;//最多MAXN种颜色 即最多MAXN种不同的点 
     5 
     6 char s1[12], s2[12];
     7 int deg[MAXN];
     8 int trie[MAXN][27], cnt, tot;
     9 int id[MAXN], pre[MAXN];
    10 
    11 int insert(char s[12])
    12 {
    13     int flag = 1;
    14     int len = strlen(s);
    15     int root = 0;
    16     for(int i = 0; i < len; i ++)
    17     {
    18         int id = s[i] - 'a';
    19         if(!trie[root][id])
    20         {
    21             flag = 0;  //单词之前没出现过 
    22             trie[root][id] = ++ cnt;
    23         }
    24         root = trie[root][id];
    25     }
    26     if(!flag)
    27     {
    28         tot ++;
    29         id[root] = tot;
    30         return id[root];
    31     }
    32     else
    33         return id[root];
    34 }
    35 
    36 int find(int x)
    37 {
    38     if(pre[x] == x)
    39         return x;
    40     else
    41     {
    42         int root = find(pre[x]);
    43         pre[x] = root;
    44         return pre[x];
    45     }
    46 }
    47 
    48 int main()
    49 {
    50     for(int i = 1; i <= MAXN + 1; i ++)
    51         pre[i] = i;
    52     while(scanf("%s%s", s1, s2) != EOF)
    53     {
    54         int a = insert(s1), b = insert(s2);//返回的是颜色所对应的序号
    55         deg[a] ++, deg[b] ++; //点的度数 判断是否存在欧拉路径 
    56         int x = find(a), y = find(b); //查找根节点 
    57         if(x != y)
    58             pre[y] = x;
    59     }
    60     int flag = 1;
    61     for(int i = 1; i < tot; i ++) //总共有tot个不同的点 
    62         if(find(i) != find(i + 1))
    63         {
    64             flag = 0;
    65             break;
    66         }
    67     if(flag == 0)
    68         printf("Impossible
    ");
    69     else
    70     {
    71         int xx = 0;
    72         for(int i = 1; i <= tot; i ++)
    73             if(deg[i] % 2)
    74                 xx ++;
    75         if(xx == 0 || xx == 2)
    76             printf("Possible
    ");
    77         else
    78             printf("Impossible
    ");
    79     }
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    51 Nod 1035 最长的循环节 (此题还不是很懂,日后再看)
    51 Nod 1101 换零钱(动态规划好题)
    51 Nod 1101 换零钱(动态规划好题)
    51 Nod 1163 最高的奖励
    51 Nod1042 数字0到9的数量
    51 Nod 1629 B君的圆锥
    iterrows(), iteritems(), itertuples()对dataframe进行遍历
    pandas计数 value_counts()
    scikit_learn逻辑回归类库
    Python中的深拷贝和浅拷贝
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11296325.html
Copyright © 2011-2022 走看看