poj2513—并查集+欧拉回路+线段树

来源:互联网 发布:己知a b c=1,求证 编辑:程序博客网 时间:2024/05/01 08:21

Description

You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

Input

Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.

Output

If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.

Sample Input

blue redred violetcyan blueblue magentamagenta cyan

Sample Output

Possible

这道题大意就是给你几个木棍,木棍两端有颜色,端点颜色相同的可以相连,问:这些木棍可以连城一条线吗? 


这道题是我做了很久字典树a的不水的一道题,哈哈哈


思路:我也是看大神博客的思路想的。。。。简直是给大神跪了。

其实他的就是问能不能一笔画将所有的木棍链接起来。。就是一个欧拉回路问题

这里我们要考虑度的问题。当度(这里的度=同种颜色的个数)为奇数的颜色》=3或者==1时候,就不能构成欧拉回路(这里不要求要会到起点)


首先我们需要给每个颜色附一个编号,然后我们用并查集建图看建图建好以后有几个连通块,要是只有一个连通块就可以,要是是森林就不行。。。。





#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define inff -0x3fffffff
using namespace std;
int color[10000];  
int mxx; // 统计不同颜色的个数

struct node
{
    node *next[30];
    int id;
    bool istrue;

    int cnt;
    node()
    {
        memset(next,NULL,sizeof(next));
        istrue=false;
        id=0;  //颜色编号

        cnt=0;//同种颜色的个数

    }
};
int sum;


/////////////////////////////////////////////////////

int  inser(node *root,char *s)
{
    int i;
    node *p;
    int x;
    int len;
    p=root;
    len=strlen(s);
    for(i=0;i<len;i++)
    {
        x=s[i]-'a';
        if(p->next[x]==NULL)
            p->next[x]=new node;
        p=p->next[x];
    }
    if(p->istrue==false)
    {
        p->istrue=true;
        sum++;
        p->id=sum;

       p->cnt++;
    }
    color[p->id]=p->cnt;
    mxx=max(mxx,p->id);
    return p->id;
}

//////////////////////////////////////////////////字典树用于个每中颜色附一个编号



int fa[100000];  

///////////////////////////////并查集判断联通性,就直接上并查集就可以了
int fin(int x)
{
    if(fa[x]==x)
    {
        return x;
    }
    return fin(fa[x]);
}
int unio(int x,int y)
{
    int fx,fy;
    fx=fin(x);
    fy=fin(y);
    if(fx!=fy)
    fa[fy]=fx;
}
//////////////////////////////////////////

int main()
{
    int i,j;
    int n;
    char str1[100],str2[100];
    node *root=new node;
    mxx=inff;
    sum=0;
    int du=0;
    int x,y;


    for(i=1;i<=10000;i++)
    {
        fa[i]=i;
    }
    while(~scanf("%s %s",str1,str2))
    {
       x=inser(root,str1);
       y=inser(root,str2);
       unio(x,y);    ////j建图
    }
      n=fin(1);
     for(i=1;i<=mxx;i++)
     {
        if(color[i]%2==1)
            du++;  //先判断度为奇数的节点
     }
     if(du==1||du>=3)
     {
         printf("Impossible\n");
         return 0;
     }
     else
     {
         for(i=1;i<=mxx;i++)
         {
             if(fin(i)!=n)//看图是一个树,还是一个森林
             {
                  printf("Impossible\n");
                  return 0;
             }
         }
         printf("Possible\n");
     }
}

0 0
原创粉丝点击