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

    Colored Sticks

    Time Limit: 5000MS

     

    Memory Limit: 128000K

    Total Submissions: 23116

     

    Accepted: 6095

    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.

    Sample Input

    blue red
    red violet
    cyan blue
    blue magenta
    magenta cyan

    Sample Output

    Possible

    Hint

    Huge input,scanf is recommended.

    Source

    The UofA Local 2000.10.14

     解题报告:题意就是给我们n个带颜色的木棍,看是否能排成一排(相接的颜色必须是一样的),

    解题思路是看的别人的:判断无向图中是否存在欧拉通路,判断条件是:

    1、有且只有两个度为奇数的节点

    2、图是连通的

    由于节点是字符串,因此我们可以利用字典树将其转换成一个颜色序号。这样,统计每种颜色的出现次数就可以了。判断图是否连通,可以利用并查集:若最后所有节点在同一个集合,则图是连通的。

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    const int MAX = 500010;
    using namespace std;
    int father[MAX];//father[x]表示x的父节点 
    int rank[MAX];//rank[x]表示x的秩
    int degree[MAX];//degree记录节点的度 
    int num = 0;//记录字典树有效节点个数 
    struct Trie//字典树节点的类型
    {
        int flag;
        struct Trie *next[26];
    };
    struct Trie *Root;//字典树的根节点
    struct Trie *NewSet()//创建新节点的函数
    {
        int i;
        struct Trie *p;
        p = (struct Trie *)malloc(sizeof(struct Trie));//开辟新节点
        for (i = 0; i < 26; ++i)//初始化
        {
            p->next[i] = NULL;
        }
        p->flag = 0;
        return p;
    }
    int Insert(char *s)//以Root为根插入字符串函数
    {
        int i, len;
        struct Trie *p;
        p = Root;
        len = strlen(s);
        for (i = 0; i < len; ++i)
        {
            //节点不存在时创建新的节点
            if (p->next[s[i] - 'a'] == NULL)
            {
                p->next[s[i]- 'a'] = NewSet();
            }
            p = p->next[s[i] -'a'];
        }
        if (p->flag == 0)
        {
            p->flag = ++num;//得到并返回颜色节点序号 
        }
        return p->flag;
    }
    void MakeSet()//初始化函数
    {
        int i;
        for (i = 0; i < MAX; ++i)
        {
            father[i] = i;
            rank[i] = 0;
            degree[i] = 0;
        }
    }
    int Find(int i)
    {
        if (father[i] != i)//路径压缩
        {
            father[i] = Find(father[i]);
        }
        return father[i];
    }
    void Merge(int x, int y)//合并函数
    {
        int i, j;
        i = Find(x);
        j = Find(y);
        if (i != j)
        {
            if (rank[i] > rank[j])
            {
                father[j] = i;
            }
            else
            {
                if (rank[i] == rank[j])
                {
                    rank[j] ++;
                }
                father[i] = j;
            }
        }
    }
    int main()
    {
        int i, sum, x, y;
        char str1[26], str2[26];
        MakeSet();
        Root = NewSet();
        while (scanf("%s%s", str1, str2) != EOF)
        {
            x = Insert(str1);
            y = Insert(str2);
            degree[x] ++;//度数加一
            degree[y] ++;
            Merge(x, y);
        }
        sum = 0;//记录度数为奇数的个数
        //求度数为奇数的点的个数
        for (i = 0; i < num; ++i)
        {
            if (degree[i] % 2)
            {
                sum ++;
            }
        }
        int Flag = 1;//假设可以连在一块
        //若度大于2则肯定不可能
        if (sum > 2)
        {
            Flag = 0;
        }
        else//判断图是否连通
        {
            for (i = 2; i < num; ++i)//是否所有的点在一个集合中
            {
                if (Find(i) != Find(1))//若不在一个集合中
                {
                    Flag = 0;
                }
            }
        }
        if (Flag)
        {
            printf("Possible\n");
        }
        else
        {
            printf("Impossible\n");
        }
        return 0;
    }

     

  • 相关阅读:
    sessionstorage中存储JSON数据
    JS + Canvas画图Demo
    JavaWeb中实现通过邮箱找回密码
    javaWeb实现验证码--代码超简单
    maven的下载、安装及配置
    web端百度地图API实现实时轨迹动态展现
    java存储数据到本地txt文件中
    java读取地址数据文件
    在服务器的tomcat中部署手机apk项目,浏览器或手机下载不能根据URL下载和安装apk文件
    虚拟机类加载机制
  • 原文地址:https://www.cnblogs.com/lidaojian/p/2444747.html
Copyright © 2011-2022 走看看