poj 2513 Colored Sticks

http://poj.org/problem?id=2513

和离散数学有关  欧拉回路问题

同一颜色的标记为同一点 同一stick 的两端为相连状态

数学什么的 最不擅长了 看了别人的解析

两个限制条件

1  图为联通  可用并查集判断

2  度 (出度+入度)数为基数的点为0 或者为 2   输入时相加

不满足上述两个条件中的任何一个  都Impossible

存颜色和查询要用字典树 用map超时

代码及其注释:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<string>

#include<map>

#include<queue>

#include<cmath>

#define LL long long



using namespace std;



const int N=550100;

int f[N];//并查集

int num[N];//度(出度+入度)

int I;//总节点数 全局变化

struct node

{

    struct node *next[26];

    int k;

}*head;

inline int findx(int x)

{

    if(f[x]!=x)

    f[x]=findx(f[x]);

    return f[x];

}

int insert(char s[])//插入颜色 并返回颜色的对应数字

{

    struct node *t,*w;

    int n=strlen(s);

    t=head;

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

    {

        if(t->next[s[i]-'a']==NULL)

        {

            w=new node;

            for(int j=0;j<26;++j)

            w->next[j]=NULL;

            w->k=-1;

            t->next[s[i]-'a']=w;

        }

        t=t->next[s[i]-'a'];

    }

    if(t->k==-1)

    t->k=I++;

    return t->k;

}

int main()

{

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

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

    {

        f[i]=i;

        num[i]=0;

    }

    head=new node;

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

    head->next[i]=NULL;

    head->k=-1;

    char stemp1[12],stemp2[12];

    I=0;

    int k1,k2;

    while(scanf("%s %s",stemp1,stemp2)!=EOF)

    {

        k1=insert(stemp1);

        k2=insert(stemp2);

        int l1=findx(k1);

        int l2=findx(k2);

        if(l1!=l2)//并查集 合并

        f[l1]=k2;

        ++num[k1];//增加度

        ++num[k2];

    }

    int l;

    int k=findx(0);

    int sum=0;

    for(l=0;l<I;++l)

    {

        if(findx(l)!=k)//图不联通

        {

           printf("Impossible\n");

           return 0;

        }

        if(num[l]%2)

        ++sum;

    }

    if(sum==0||sum==2)//只有基数度的点为0 和 为2 时可以

    printf("Possible\n");

    else

    printf("Impossible\n");

    return 0;

}

  

 

你可能感兴趣的:(color)