POJ 2513 Colored Sticks (並查集 Trie樹 歐拉回路)

Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total 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 red
red violet
cyan blue
blue magenta
magenta 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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章