poj 2513 欧拉回路+并查集+字典树

来源:互联网 发布:win10缺少一个网络协议 编辑:程序博客网 时间:2024/05/20 23:55

Colored Sticks
Time Limit: 5000MS Memory Limit: 128000KTotal Submissions: 35912 Accepted: 9388

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

Hint

Huge input,scanf is recommended.


题意:

每一行给定一根木棍,每一根首尾各有一种颜色

求是否可以组合成一条直线,接口处的颜色是一样的


题解:

由于数据量很大,使用map肯定会超时的

因此使用字典树存储颜色单词

使用并查集检测是不是连通图

使用欧拉通路的判断定理进行判断就可以了


注意:

题目说空数据的时候要输出possible

下面给出两种代码,第一份代码是不需要判断就已经默认了

第二份代码需要判断的


两种办法第二种更加清晰一点,但是主要的思路是一样的



注意两种并查集中的查的写法

注意%2与&1的相同的作用


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int father[1000000];struct Node{    int next[27];    int id;    int flag;}node[1000000];int tot;int a[1000000],pos=0;void init(){    for(int i=1;i<1000000;i++)        father[i]=i;    tot=0;}int insert_word(char *str){    int p=0;    int len=strlen(str);    for(int i=0;i<len;i++){        if(!node[p].next[str[i]-'a'])            node[p].next[str[i]-'a']=++tot;        p=node[p].next[str[i]-'a'];    }    if(node[p].flag==0){        a[pos++]=p;        node[p].flag=1;    }    node[p].id++;    return p;}int find_it(int x){    int tempx=x,t;    while(tempx!=father[tempx])        tempx=father[tempx];    while(x!=father[x])    {        t=father[x];        father[x]=tempx;        x=t;    }    return tempx;}int main(){    init();    int t1,t2,tx,ty;    char str1[15],str2[15];    //freopen("in.txt","r",stdin);    while(scanf("%s%s",str1,str2)!=EOF)    {        t1=insert_word(str1);        t2=insert_word(str2);        tx=find_it(t1);        ty=find_it(t2);        if(tx>=ty)            father[tx]=ty;        else            father[ty]=tx;    }    int fath=0;    int flag=1,cnt=0;    for(int i=0;i<pos;i++){        int temp=a[i];        if(node[temp].id%2==1)            cnt++;        if(fath==0)            fath=find_it(father[temp]);        else if(fath!=find_it(father[temp])){            flag=0;            break;        }    }    if(cnt!=0&&cnt!=2)        flag=0;    if(flag)        puts("Possible");    else        puts("Impossible");    return 0;}



#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int father[1000000];int id[1000000];struct Node{    int next[27];    int flag;}node[1000000];int tot,num;void init(){    for(int i=1;i<1000000;i++)        father[i]=i;}int insert_word(char *str){    int p=0;    int len=strlen(str);    for(int i=0;i<len;i++){        if(!node[p].next[str[i]-'a'])            node[p].next[str[i]-'a']=++tot;        p=node[p].next[str[i]-'a'];    }    if(node[p].flag==0)        node[p].flag=++num;    return node[p].flag;}int find_it(int x){    if(x!=father[x])        father[x]=find_it(father[x]);    return father[x];}int main(){    init();    int t1,t2,tx,ty;    char str1[15],str2[15];    //freopen("in.txt","r",stdin);    while(scanf("%s%s",str1,str2)!=EOF)    {        t1=insert_word(str1);        t2=insert_word(str2);        tx=find_it(t1);        ty=find_it(t2);        //并查集中的并        if(tx>ty)            father[tx]=ty;        else            father[ty]=tx;        id[t1]++;        id[t2]++;    }    int sum1=0,sum2=0;    for(int i=1;i<=num;i++){        if(find_it(i)==i)            sum1++;//判断是否连通        if(id[i]&1)            sum2++;//判断欧拉通路    }    int flag=0;    if(sum1==1&&(sum2==2||sum2==0)||(!tot))        flag=1;    if(flag)        puts("Possible");    else        puts("Impossible");    return 0;}


0 0
原创粉丝点击