poj_2513 Colored Sticks(字典树+并查集+欧拉通路)

Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 36048   Accepted: 9431

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.

用字典树保存字符串到id的映射。用并查集判断图是否连通。然后根据判断欧拉通路的定理:
图中无奇度顶点或恰好有两个奇度顶点。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <bitset>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#define FOP freopen("data.txt","r",stdin)
#define inf 0x3f3f3f3f
#define maxn 500010
#define mod 1000000007
#define PI acos(-1.0)
#define LL long long
using namespace std;

struct Node
{
    Node *br[26];
    int num;
};

Node *head;
int cot = 0;
int degree[maxn];
int pre[maxn];

void initTrie()
{
    head = new Node;
    for(int i = 0; i < 26; i++) head->br[i] = NULL;
    head->num = cot++;
}

int insertTrie(char *str)
{
    Node *t, *s = head;
    int len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        int id = str[i] - 'a';
        if(s->br[id] == NULL)
        {
            t = new Node;
            for(int j = 0; j < 26; j++)
            {
                t->br[j] = NULL;
            }
            t->num = 0;
            s->br[id] = t;
        }
        s = s->br[id];
        if(i == len - 1) s->num = cot++;
    }
    return cot-1;
}

int findTrie(char *str)
{
    Node *s = head;
    int c;
    int len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        int id = str[i] - 'a';
        if(s->br[id] == NULL) return 0;
        else s = s->br[id], c = s->num;
    }
    return c;
}

int findUF(int x)
{
    int r = x;
    while(pre[r] != r) r = pre[r];

    int i = x, j;
    while(i != r)
    {
        j = pre[i];
        pre[i] = r;
        i = j;
    }

    return r;
}

void joinUF(int x, int y)
{
    int fx = findUF(x), fy = findUF(y);
    if(fx != fy) pre[fx] = fy;
}

int main()
{
    //FOP;
    initTrie();
    for(int i = 1; i < maxn; i++) pre[i] = i;
    char str1[12], str2[12];
    int id1, id2;
    while(~scanf("%s %s", str1, str2))
    {
        id1 = findTrie(str1);
        if(!id1) id1 = insertTrie(str1);
        id2 = findTrie(str2);
        if(!id2) id2 = insertTrie(str2);
        joinUF(id1, id2);
        degree[id1]++, degree[id2]++;
    }
    int flag = 0;
    int fa = findUF(1);
    for(int i = 1; i < cot; i++)
    {
        if(degree[i] & 1) flag++;
        if(findUF(i) != fa) {flag = -1; break;}
    }
    if(flag == 0 || flag == 2) printf("Possible\n");
    else printf("Impossible\n");
    return 0;
}


猜你喜欢

转载自blog.csdn.net/christry_stool/article/details/53033918