zoukankan      html  css  js  c++  java
  • POJ 2513 Colored Sticks

    题目大意:给定一捆木棒,每根木棒的每个端点涂有某种颜色。问:是否能将这些棒子首位项链,排成一条直线,且相邻两根棍子的连接处的颜色一样。

    解题思路:此题是一道典型的判断欧拉回路或欧拉通路的问题,以木棍的端点颜色为顶点。方法是:先用并查集判断图是否连通,然后统计奇度顶点的个数sumj , 如果 sumj == 0 , 则图中存在欧拉回路 ;如果 sumj == 2  , 则图中存在欧拉通路 ; 如果 sumj > 2 ,则图中不存在欧拉通路。但是此题的关键是如何给端点颜色编号,一开始,我用map映射,结果TLE,所以,我就用到了Trie 树。

            Ps:此题有坑!!当没有输入时,应当输出 Possible 。。

    具体请看代码:

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std ;
    const int MAXN = 3e6;
    int set[MAXN] ;
    char s1[100] ;
    char s2[100] ;
    int cnt ;  // 给端点编号
    int d[MAXN] ; // 统计每个顶点的度
    struct Tnode
    {
        int du ;
        int xu ;
        Tnode *next[26] ;
        Tnode()
        {
            du = 0 ;
            xu = 0 ;
            memset(next , 0 ,sizeof(next)) ;
        }
    } ;
    int find(int x)  // 并查集
    {
        int r = x ;
        while (r != set[r])
        {
            r = set[r] ;
        }
        return r ;
    }
    int inse(char * str , Tnode * root)
    {
        Tnode *p = root ;
        while (*str)
        {
            int id = *str - 'a' ;
            if(p -> next[id] == NULL)
            {
                p -> next[id] = new Tnode ;
            }
            ++ str ;
            p = p -> next[id] ;
        }
        if(p -> du == 0)
        {
            p -> xu = ++ cnt ;  // 顶点颜色的编号从 1 开始
        }
        p -> du ++ ;
        d[p -> xu] = p -> du ;
        return p -> xu ;
    }
    int main()
    {
        memset(d , 0 , sizeof(d)) ;
        int i ;
        for(i = 1 ; i <= MAXN ; i ++)
        {
            set[i] = i ;
        }
        cnt = 0 ;
        Tnode *root = new Tnode ;
        while (scanf("%s%s" , s1 , s2) != EOF)
        {
            int x = inse(s1 , root) ;
            int y = inse(s2 , root) ;
            int tx = find(x) ;
            int ty = find(y) ;
            if(tx < ty)
            {
                set[ty] = tx ;
            }
            else
            {
                set[tx] = ty ;
            }
        }
        int fz = 0 ; // 判断图的连通的分支个数
        int sumj = 0 ; // 统计奇度顶点的个数
        for(i = 1 ; i <= cnt ; i ++)
        {
            if(set[i] == i)
            {
                fz ++ ;
            }
            if(d[i] % 2 == 1)
            {
                sumj ++ ;
            }
        }
        if(cnt == 0)
        {
            puts("Possible") ;
        }
        else if(fz == 1)
        {
            if(sumj > 2)
            {
                puts("Impossible") ;
            }
            else
            {
                puts("Possible") ;
            }
        }
        else
        {
            puts("Impossible") ;
        }
        return 0 ;
    }
    


  • 相关阅读:
    Windows 之间用rsync同步数据(cwRsyncServer配置)
    学习blus老师js(5)--DOM操作应用高级
    学习blus老师js(4)--DOM
    scrollWidth,clientWidth,offsetWidth的区别 ---转载的
    学习blus老师js(3)--定时器的使用
    学习blus老师js(2)--深入JavaScript
    学习blus老师js(1)--基础
    转转转---ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法
    转转转--oracle 去重并按时间排序取第一条
    java正则表达式实战例子,持续更新,记下来后面就不用重新写了。。。
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3225771.html
Copyright © 2011-2022 走看看