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

来源:互联网 发布:谷歌输入法 网络词库 编辑:程序博客网 时间:2024/05/27 20:17
Colored Sticks
Time Limit: 5000MS Memory Limit: 128000KTotal 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 redred violetcyan blueblue magentamagenta 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 longusing 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;}


0 0
原创粉丝点击