POJ 2513-Colored Sticks(連線木棍-trie樹+並查集+尤拉通路)

kewlgrl發表於2017-03-31
Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 37049   Accepted: 9729

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

The UofA Local 2000.10.14


題目意思:

有一堆木棍, 木棍的兩個端點用一些不同的顏色著色, 將它們在端點處連線起來,要求端點的顏色相同,判斷是否能夠實現。


解題思路:

啊(○´・д・)ノ本來以為要用這麼多知識點就很困難,結果好像…(⊙v⊙)嗯直接用尤拉回路判斷的充要條件還是很簡單的。

將不同的顏色視為圖的節點,木棍本身視為邊,建圖。

資料量巨大,map妥妥超時,用trie樹儲存記錄不同顏色的序號,並查集判斷是否只有一個父節點(這種情況下圖才是連通的),若滿足題設條件,則圖中必然存在尤拉通路。


#include<cstdio>
#include<cstring>
#include<cmath>
#include<iomanip>
#include<cstdlib>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define MAXN 510010
#define INF 0x3f3f3f3f
int trie[MAXN][26];//字典樹
int num[MAXN][26];//顏色的序號
int degree[MAXN],fa[MAXN];//顏色出現的次數、並查集
int n,e;//樹的數目和序號
//字典樹
int Insert(char s[])
{
    int j=0;
    int len=strlen(s);
    for(int i=0; i<len; i++)
        if(trie[j][s[i]-'a']) j=trie[j][s[i]-'a'];
        else
        {
            trie[j][s[i]-'a']=++e;
            j=trie[j][s[i]-'a'];
        }
    if (num[j][s[len-1]-'a']==0) //當前字母沒有出現過
        num[j][s[len-1]-'a']=++n;
    return num[j][s[len-1]-'a'];//顏色的序號
}
//並查集
int Find(int x)
{
    if(x!=fa[x]) fa[x]=Find(fa[x]);
    return fa[x];
}
void Join(int i,int j)
{
    int p=Find(i);
    int q=Find(j);
    if(p!=q) fa[p]=q;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("G:/cbx/read.txt","r",stdin);
//freopen("G:/cbx/out.txt","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
     n=e=0;
    memset(trie,0,sizeof(trie));
    memset(num,0,sizeof(num));
    memset(degree,0,sizeof(degree));
    for(int i=1; i<MAXN; i++)
        fa[i]=i;
    char s1[11],s2[11];
    while(cin>>s1>>s2)
    {
        int p=Insert(s1),q=Insert(s2);//插入字典樹,得到顏色的序號
        ++degree[p],++degree[q];//更新度數
        Join(p,q);
    }
    int cnt=0;//父節點的個數
    for(int i=1; i<=n; i++)//是否只有一個父節點
    {
        if(i==Find(i)) ++cnt;
        if (cnt>1) break;
    }
    if (cnt>1) cout<<"Impossible"<<endl;//只有一個父節點時是不連通的
    else
    {
        int sum=0;
        for(int i=1; i<=n; i++)
            if (degree[i]%2) ++sum;//統計度為奇數的點的個數
        if(sum==0||sum==2) cout<<"Possible"<<endl;//無向圖尤拉回路中度為奇數的點的個數是0/2
        else cout<<"Impossible"<<endl;
    }
}


相關文章