POJ 2513 Colored Sticks

来源:互联网 发布:淘宝 新店 低价冲信誉 编辑:程序博客网 时间:2024/04/26 05:26

给你250000个棒子,棒子两头有颜色,问你可不可以用完所有的棒子,把棒子连起来,并且使得棒子相连的两头颜色一样。

其实就是求欧拉回路。

无向图存在欧拉路的充要条件为:

   1->图是连通的;

   2->所有节点的度为偶数,或者有且只有两个度为奇数的节点。

判断图的连通性,用并查集搞定。又题目给的棒子颜色是字符串,所以要用trie树把每个颜色的编号记录下来。

注意,这里用map会超时。。因为map基于hash,并不高效,所以这里需要用trie树来处理。。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define MAX 260000int uset[MAX],degree[26000];int BCG_root(int k){    if(k==uset[k])return k;        return uset[k]=BCG_root(uset[k]);}int BCG_init(){    for(int i=0;i<MAX;++i)        uset[i]=i;    return 0;}struct node{    int flag; //如果是终止状态,则标记是哪个字符    int tag;    int next[26];    int init()    {        memset(next,-1,sizeof(next));        flag=0;        tag=0;        return 0;    }}trie[260000];int size=1;const int root=0;int val(char a){    return a-'a';}int insert(char* s,int k){    int p=root;    for(int i=0;s[i];++i)    {        int v=val(s[i]);        if(trie[p].next[v]==-1)        {            trie[p].next[v]=size;            trie[size].init();            ++size;        }        p=trie[p].next[v];    }    trie[p].tag=1;    trie[p].flag=k;    return 0;}int match(char* s){    int p=root;    for(int i=0;s[i];++i)    {        int v=val(s[i]);        p=trie[p].next[v];        if(trie[p].tag)        return trie[p].flag;    }    return 0;}void init(){    size=1;    trie[root].init();    return ;}int main(){    char str[15];    int n,cnt,i,j,anc,sum,t1,t2;    init();    BCG_init();    cnt=1;    memset(degree,0,sizeof(degree));    while (scanf("%s",str) != EOF)   // for (int k=0; k<5; k++)    {      //  scanf("%s",str);        j=match(str);        if (j == 0)        {            insert(str,cnt);            degree[cnt]++;            t1=cnt;            cnt++;        }        else        {            degree[j]++;            t1=j;        }        scanf("%s",str);        j=match(str);        if (j == 0)        {            insert(str,cnt);            degree[cnt]++;            t2=cnt;            cnt++;        }        else        {            degree[j]++;            t2=j;        }        uset[BCG_root(t1)]=BCG_root(t2);    }    anc=BCG_root(1);    sum=0;  //  printf("anc=%d\n",anc);    for (i=1; i<cnt; i++)    {       // printf("%d\n",i);       // printf("%d\n",BCG_root(i));       // printf("!!\n");        if (BCG_root(i) != anc)        {          //  printf("@");          break;        }        if (degree[i]%2 == 1)            sum++;    }    if (i != cnt || (sum != 2 && sum != 0))        printf("Impossible\n");    else        printf("Possible\n");}


原创粉丝点击