【POJ 2513】Colored Sticks

【POJ 2513】Colored Sticks

并查集+字典树+欧拉通路
第一次做这么混的题。。太混了……
不过题不算难 字典树用来查字符串对应图中的点 每个单词做一个点(包括重复单词
题意就是每个边走且直走一次(欧拉通路
欧拉图的判定: 没有或者只有两个奇数度的点的图叫做欧拉图

有这些就可以解答此题了
另外需要注意题目范围是25W个木棍 所以最多可能有50W个点 卡了好多个RE

代码如下:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#define LL long long
#define INF 0x3f3f3f3f

using namespace std;

typedef struct Trie
{
    int dic[26];
    int data;
}Trie;

Trie tr[777777];
int in[555555];
int pre[555555];
int tp,data;

int SetNode()
{
    memset(tr[tp].dic,-1,sizeof(tr[tp].dic));
    tr[tp].data = -1;
    return tp++;
}

int Get(int site,char *ch)
{
    int i,k;
    for(i = 0; ch[i]; ++i)
    {
        if(tr[site].dic[ch[i]-'a'] == -1)
        {
            k = SetNode();
            tr[site].dic[ch[i]-'a'] = k;
        }else k = tr[site].dic[ch[i]-'a'];
        site = k;
    }
    if(tr[site].data == -1) tr[site].data = data++;
    return tr[site].data;
}

int Find(int x)
{
    return pre[x] = ( (pre[x] == x)? pre[x]: Find(pre[x]));
}

int main()
{
    char a[23],b[23];
    int i,aa,bb,j,f,k,r;
    tp = data = j = 0;
    SetNode();
    for(i = 0; i < 250050; ++i) pre[i] = i;
    memset(in,0,sizeof(in));
    while(~scanf("%s %s",a,b))
    {
        aa = Get(0,a);
        bb = Get(0,b);
        k = Find(aa);
        r = Find(bb);

        pre[k] = r;
        in[aa]++;
        if(in[aa]&1) j++;
        else j--;
        in[bb]++;
        if(in[bb]&1) j++;
        else j--;
    }

    int cnt=0;
    for(int i=0;i<data;i++)
    {
        if(pre[i]==i)
            cnt++;
    }
    if((cnt==1||cnt==data)&&(j==0||j==2)) puts("Possible");
    else puts("Impossible");
    return 0;
}

你可能感兴趣的:(并查集,字典树,欧拉图)