Colored Sticks(彩色棒)

poj 2513

题目大意:给一些彩色棒,看能不能组成一个

解决:trie+无向图欧拉路(偶数结点度数为0或者2)

clude <iostream> 
#include <cstring>
#include <cstdio>
using namespace std;
struct node
{
      int next[26];
      int wordNo;
};
int top;
int num;
node tree[2000000];
short adj[510010];

int data[510010];
void init()
{
    top=1;
    num=0;
    memset(data,-1,sizeof(data));
    memset(tree[0].next,0,sizeof(tree[0].next));
    tree[1].wordNo=-1;
}
int build_trie(char *str)
{
    int id,i=0;
    while(*str)
    {
        id=*str-'a';
        if(tree[i].next[id]==0)
        {
            tree[i].next[id]=top;
            tree[top].wordNo=-1;
            memset(tree[top].next,0,sizeof(tree[top].next));
            top++;
        }
        i=tree[i].next[id];
        str++;
    }
    if(tree[i].wordNo == -1)tree[i].wordNo=num++;
    return tree[i].wordNo;
}


int find(int x)
{
    if(data[x]<0)return x;
    return data[x]=find(data[x]);
}
void merge(int a,int b)
{
    int fa=find(a);
    int fb=find(b);
    if(fa==fb)return ;
    int t=data[fa]+data[fb];
    if(fa>fb){data[fa]=fb;data[fb]=t;}
    else {data[fb]=fa;data[fa]=t;}
}
int main()
{
    int i,n,beg,end;
    char s1[15],s2[15];
    init();
    while(scanf("%s%s",s1,s2)!=EOF)
    {//并查集判断联通性,trie求编号
                beg=build_trie(s1);
                end=build_trie(s2);
                adj[beg]++;
                adj[end]++;
                merge(beg,end);
    }
    int root=0,tot=0;
    bool flag=0;
    for(i=0;i<num ;i++)
    {
            if(data[i]<0)
            {
                 root++;
                 if(root>1){flag=1;break;}
            }
            if(adj[i]&1)
            {
                tot++;
                if(tot>2){flag=1;break;}
            }
    }//判断是否存在无向图的欧拉路
    if(!flag && (tot==0 || tot==2))puts("Possible");
    else puts("Impossible");
    return 0;
}

原文地址:https://www.cnblogs.com/hpustudent/p/2161310.html