POJ 2513 Colored Sticks (并查集 Trie树 欧拉回路)

来源:互联网 发布:龙华行知小学 编辑:程序博客网 时间:2024/05/20 23:36

Colored Sticks
Time Limit: 5000MS Memory Limit: 128000KTotal Submissions: 30515 Accepted: 8056

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.

先不说这题有多坑 先说这题的题意:

给一些棒子,每根棒子的两头有颜色,用两个字符串给出。问能不能将这些棒子首尾相接,使得首尾的颜色都相同。

刚开始想的非常简单,直接用map做个映射然后判断有没有欧拉路径(两个或者零个度为奇数的点)

直接TLE了,没办法,改用trie树存字符串,然后光荣的WA了

后来走投无路看了网上题解,说是有不连通的情况。好吧 是我自己的问题,果断加了一段并查集。

最坑的地方出现了 ,居然还是wa了

然后就是一段漫长的交题过程。。。。

中午回去睡了一觉,下午来看,想了想,加了一组什么都没有的特判(其实就是乱加了)

结果过了。

过了。。

说不下去了。。太难过了。。。难过

代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;int trie[750005][30];int ok[750005];int fa[750005];int id[750005];int sz,num;int getfa(int x){    return fa[x] != x? fa[x] = getfa(fa[x]) : x;}void init(){    for(int i=0;i<250005;i++)fa[i] = i;    memset(trie,0,sizeof(trie));    memset(ok,0,sizeof(ok));    memset(id,0,sizeof(id));    sz = 1;    num = 0;}int in(char *s) {    int cur = 1;    for (int i= 0; s[i]; i++) {        int c = s[i]-'a';        if (!trie[cur][c]){            trie[cur][c]= ++sz;        }        cur = trie[cur][c];    }ok[cur]++;    if(ok[cur]==1){id[cur] = ++num;return num;}    return id[cur];}int main(){    char str1[15],str2[15];    init();    while(scanf("%s%s",str1,str2)==2){        int a,b;        a = in(str1);        b = in(str2);        fa[getfa(a)] = getfa(b);    }    if(num == 0){cout<<"Possible"<<endl;return 0;}    int flag,cnt =0,cnt2 = 0;    for(int i=1;i<=sz;i++){        if(ok[i]%2!=0)cnt++;        if(cnt>2)break;    }    for(int i=1;i<=num;i++)if(fa[i] == i)cnt2++;    if(cnt2 == 1&&(cnt == 2|| cnt ==0))flag = 1;    else flag = 0;    printf("%s\n",flag?"Possible":"Impossible");    return 0;}


0 0
原创粉丝点击