POJ 2513 Colored Sticks 解题报告

    第一次接触欧拉回路。虽然在离散数学里学过,敲代码还是第一次。

    本题是说端点颜色相同的两根木棒可连接,能否将所有的木棒连成一条直线。

    将颜色视为节点v,将木棒视为边e,构成图G。如果能找到一条一笔画的路经过所有边,那么便符合条件。也就是判断是否是欧拉回路。

    欧拉回路的条件是:

    (1) 图是连通的。

    (2) 度数为基数的点的个数是两个,或者不存在。

    连通可以通过用并查集判断。度数可以建一个数组保存当前点的度数。

    值得注意的是有全空的数据,此时应该输出Possible。这点坑了我一下,在Discuss里发现有人提出了,改一下就A了。

#include <cstdio>

#include <cstring>



const int maxn=500010;

int root[maxn];

int degree[maxn];



struct Node

{

    int next[26];

    int id;

} dic[1000000];

int index=0;

int id=0;



int find(int x)

{

    return root[x]?root[x]=find(root[x]):x;

}



bool union_set(int a,int b)

{

    a=find(a);

    b=find(b);

    if(a==b)

        return false;

    root[b]=a;

    return true;

}



int insert(char* s)

{

    int now=0;

    int len=strlen(s);

    for(int i=0;i<len;i++)

    {

        int next=s[i]-'a';

        if(dic[now].next[next]==0)

            dic[now].next[next]=++index;

        now=dic[now].next[next];

    }

    if(dic[now].id==0)

        dic[now].id=++id;

    return dic[now].id;

}



int main()

{

//    freopen("in.txt","r",stdin);

    int num=1;

    char s1[20],s2[20];

    while(~scanf("%s%s",s1,s2))

    {

        int a=insert(s1);

        int b=insert(s2);

        degree[a]++;

        degree[b]++;

        if(union_set(a,b))

            num++;

    }

    if(num==id || id==0)

    {

        int count=0;

        for(int i=1;i<=id;i++) if(degree[i]&1)

        {

            count++;

            if(count==3)

                break;

        }

        if(count==0 || count==2)

        {

            printf("Possible\n");

            return 0;

        }

    }

    printf("Impossible\n");

}

 

你可能感兴趣的:(color)