Play on Words 并查集加欧拉回路

136 篇文章 0 订阅
46 篇文章 0 订阅
//用并查集的时候先将当做无向图来处理判断图的连通性。
//然后用欧拉路的定义来求解。存在欧拉回路的条件是:所有点出度==入度。
//存在欧拉道路的条件是:有且仅有两个点出度!=入度,且出度和入度之差为1.其余点出度==入度
#include <stdio.h>
#include <cstring>
int f[27];
int in[27];
int out[27];
bool vis[27];
int find(int x)
{
    if(x!=f[x])
        f[x]=find(f[x]);
    return f[x];
}
void un(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y) return ;
    f[y]=x;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1; i<=26; i++)
        {
            in[i]=0;
            out[i]=0;
            f[i]=i;
            vis[i]=false;
        }
        char op[1001];
        for(int i=0; i<n; i++)
        {
            scanf("%s",op);
            int x=op[0]-'a'+1;
            int y=op[strlen(op)-1]-'a'+1;
            out[x]++;
            in[y]++;
            vis[x]=true;
            vis[y]=true;
            un(x,y);
        }
        int count=0;
        for(int i=1; i<=26; i++)//如果是连通的则只有一个祖先,且必须在标记的范围内查找
        {
            if(find(i)==i&&vis[i]) count++;
        }
        if(count>=2)
        {
            printf("The door cannot be opened.\n");
            continue;
        }
        int c1=0,c2=0;
        for(int i=1; i<=26; i++)
        {
            if(in[i]==out[i])  continue;
            else//if(in[i]==out[i]+1) c1++;if(out[i]==in[i]+1) c2++;else中用这样的条件判断是错误的。因为可能in 和out的数据               
            {   //之差比1大。就不满则条件。最后二者都为0.不能控制等于1,应当控制不等于1.
                if(in[i]>out[i])
                {
                    c1++;
                    if(in[i]!=out[i]+1) c1++;
                }
                else
                {
                    c2++;
                    if(out[i]!=in[i]+1) c2++;
                }
            }
        }
        if((c1==0&&c2==0)||(c1==1&&c2==1)) printf("Ordering is possible.\n");
        else printf("The door cannot be opened.\n");
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值