nyist 230 彩色棒(并查集+欧拉图+字典树)



彩色棒

时间限制: 1000  ms  |  内存限制: 128000  KB
难度: 5
描述
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?
输入
the frist line have a number k(0<k<=10),that is the number of case. each case contais a number m,then have m line, 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 13 characters. There is no more than 250000 sticks.
输出
If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.
样例输入
1
5
blue red
red violet
cyan blue
blue magenta
magenta cyan
样例输出
Possible
上传者
苗栋栋

第一次做字典树有关的题,对这类数据结构还是有点畏惧啊,这个题目搞了我好久,还是参考了一下别人的代码才ac的,对这类数据结构还是要加强啊,还是不能灵活运用字典树。。。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXN 500002
typedef struct node
{
    int order;
    struct node *next[26];
}node;
int father[MAXN],rank[MAXN];
int visit[MAXN];
int m;
int find(int x)//其实有路径压缩的就已经比较高效了
{
  if(father[x]==-1) return x;
  return father[x]=find(father[x]);
}
  /*void Union(int x,int y)//这一段是按秩合并的,按秩合并后这个题目内存增加了不少,用时也没减少。。
{
    int fx,fy;
    fx=find(x);
    fy=find(y);
    if(fx==fy)  return ;
    if(rank[fx]>rank[fy])
               father[fy]=fx;
    else
    {
        father[fx]=fy;
        if(rank[fx]==rank[fy])
             rank[fy]++;
    }
}
*/
void Union(int x,int y)
{
    int fx,fy;
    fx=find(x);
    fy=find(y);
    if(fx!=fy)
     father[fy]=fx;
}
int search(char *s,node *T)//字典树的查找。。。
{
    int len,i,j,flag=0,id;
    node *q,*p;
    len=strlen(s);
    q=T;
    for(i=0;i<len;i++)
    {
        id=s[i]-'a';
       if(q->next[id]==NULL)
        {
            flag=1;
            p=(node *)malloc(sizeof(node));
            for(j=0;j<26;j++)
                p->next[j]=NULL;
            q->next[id]=p;
        }
        q=q->next[id];
    }
    if(flag)
    {
        q->order=m++;
        visit[q->order]=!visit[q->order];
        return q->order;
    }
    else
    {
         visit[q->order]=!visit[q->order];
        return q->order;
    }
}
int main()
{
    int t,n,i,num1,num2;
    char s1[20],s2[20];
    node *T;
    scanf("%d",&t);
    while(t--)
    {
        m=1;
        memset(rank,0,sizeof(rank));
        memset(father,-1,sizeof(father));
        memset(visit,0,sizeof(visit));
        T=(node*)malloc(sizeof(node));
        T->order=0;
        for(i=0;i<26;i++)
            T->next[i]=NULL;
        scanf("%d",&n);
        if(n==0) { printf("Possible\n"); continue ;}
        for(i=1;i<=n;i++)
        {
            scanf("%s%s",s1,s2);
            num1=search(s1,T);
            num2=search(s2,T);
            Union(num1,num2);
        }
        int ans=0,sum=0;
        for(i=1;i<m;i++)
        {
            if(father[i]==-1) ans++;
            if(visit[i]) sum++;
        }
        if(ans>1) printf("Impossible\n");
        else
        {
            if(sum==2||sum==0)
               printf("Possible\n");
            else
                printf("Impossible\n");
        }
    }
    return 0;
}

对这种代码比较长的题目,思路还是不清晰啊,代码能力还有待加强啊(开始还忘了初始化,犯这种低级错误啊)。。。 对数据结构这一块掌握的还是不够啊(树,图)都是比较重要的,各个击破!!!


你可能感兴趣的:(并查集,字典树,欧拉图,nyist)