HDU 1116 Play on Words 并查集

HDU 1116 Play on Words

欧拉回路 (并查集)

#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN = 30;
bool vis[MAXN];
int in[MAXN], out[MAXN], bin[MAXN];

int findx(int x)
{
    return x==bin[x]?x:findx(bin[x]);//通过三目运算符简化写法
    /*
    while(bin[x]!=x)
       x = bin[x];
      return x;
    */
}
void join(int a, int b)
{
    int x , y;
    x = findx(a);
    y = findx(b);
    if(x != y)
        bin[y]=x;
}
int main()
{
    int t, n;
    int l, r, i;
    char str[1005];
    int wordnum, len;
    int root;
    bool flag, flag1;
    int innum, outnum;
    int start, end;

    scanf("%d", &t);


    while(t--)
    {
        memset(vis, 0, sizeof(vis));
        memset(in, 0 ,sizeof(in));
        memset(out, 0, sizeof(out));


        for(i=1;i<MAXN;i++)
            bin[i]=i;


        flag = flag1 = true;


        innum = outnum = root = 0;


        scanf("%d", &wordnum);


        for(i=1;i<=wordnum;i++)
        {
            scanf("%s", str);


            len = strlen(str);


            start = str[0] - 'a' + 1;
            end = str[len-1] - 'a' + 1;
            vis[start] = true;
            vis[end] = true;
            out[start]++;
            in[end]++;
            join(start, end);
        }


        for(i=1;i<MAXN;i++)//欧拉路径的条件判断入度等于出度, 如果不相等,那就是
           //存在小于等于一对in,out互相相差一,否则就是不存在
        {
            if(vis[i])
            {
                if(bin[i]==i)
                    root++;
                if(in[i]!=out[i])
                {
                    if(in[i]-out[i]==1)
                        innum++;
                    else if(out[i]-in[i]==1)
                        outnum++;
                    else
                        flag1=false;
                }
            }
            if(root>1)//最后的根是否只有一个,如果有多个根说明没有遍历完全部的单词
            {
                flag = false;
                break;
            }
        }
        if(flag&&flag1&&((innum==0&&outnum==0)
      ||(innum==1&&outnum==1)))
            printf("Ordering is possible.\n");
        else
            printf("The door cannot be opened.\n");






    }


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值