EricYang

Tech Spot of Eric

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Colored Sticks

Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 19454   Accepted: 5083

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

 

这个题目涉及了多个基本数据结构和算法
虽然简单,但是很有代表性。
知识考查点:1,字典树;2,欧拉路:其中又考察了判断是否为连通图;3,并查集;
题意不难理解,可是我们得巧妙的转化一下,我们把棍子头的颜色当作节点,棍子就当作线 于是就形成了下面的图
 
poj <wbr>2513 <wbr>解题报告
那么问题就可以转化为将这个图一笔画,要求每根线段都要走到而且只能走一次,于是这就转化为了欧拉路的判断,即亮点,一,图是联通的. 二,该图每个点的度数要么全为偶数,要么有且仅有两个点的度数为奇数。

先岔开,我们建立字典树就是判断存储有多少种颜色,和每种颜色的个数分别是多少。

回到上面,图是否联通,可以在首先处理的时候把连同的点都归结到一个点上,如上面我全部归结到BLUE上,这个就是根,最后判断如果所有的点都归结在一个相同点上即联通;于是我们只要判断第二个条件,这里我们就利用二叉树保存下来的结果,判断为颜色数目为基数的个数是不是少于或者等于2,是就是POSSIBLE,不是就IMPOSSIBLE。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef struct node
{
    bool isLeaf;
    int key;
    struct node* next[26];
}Node;

const int NODE_NUM=500000;
int color[NODE_NUM+1];
int parent[NODE_NUM+1];
int color_cnt=1;
Node* root;

void createSet(int x)
{
    parent[x]=x;
}

int find(int x)
{
    if(parent[x]!=x)
       parent[x]=find(parent[x]);

    return parent[x];
}

void unionSet(int a, int b)
{
    int pa,pb;

    pa=find(a);
    pb=find(b);
    parent[pb]=pa;
}

int search(char word[15])
{
    Node *p, *temp;
    int len;
    int index;

    p=root;
    len=0;
    while(word[len])
    {
        index=word[len]-'a';
        if(!p->next[index])
        {
            temp=(Node*)malloc(sizeof(Node));
            temp->isLeaf=false;
            temp->key=-1;
            memset(temp->next,0,sizeof(temp->next));
            p->next[index]=temp;
        }
        p=p->next[index];
        len++;
    }

    if(p->isLeaf)
        return p->key;
    p->isLeaf=true;
    p->key=color_cnt;
    color_cnt++;
    return p->key;
}
int main()
{
    char str1[15], str2[15];
    int a,b;
    int m;
    int pa;

    root=(Node*)malloc(sizeof(Node));
    root->isLeaf=false;
    root->key=0;
    memset(root->next,0,sizeof(root->next));
    memset(color,0,sizeof(color));
    for(int i=1; i<=NODE_NUM; i++)
    {
        createSet(i);
    }
    m=0;

    while(scanf("%s%s",str1, str2)!=EOF)
    {
        a=search(str1);
        b=search(str2);
        color[a]++;
        color[b]++;
        unionSet(a,b);
    }

    for(int i=1; i<color_cnt; i++)
    {
        if(color[i]%2!=0)
            m++;
    }
    pa=find(1);
    for(int i=2; i<color_cnt;i++)
    {
        if(pa!=find(i))
        {
            m=-1;
            break;
        }
    }

    if(m == 2 || m == 0)
        printf("Possible\n");
    else
        printf("Impossible\n");


    return 0;
}
posted on 2011-05-04 17:10  Eric-Yang  阅读(386)  评论(0编辑  收藏  举报