欧拉回路&哈密顿回路&强连通

本文详细介绍了PlayonWords算法的实现过程,包括并查集的使用、字符入度和出度的统计以及判断字符间连接的可能性。通过实例演示,帮助读者理解并掌握该算法的核心逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hdoj  Play on Words

#include <iostream>

#include <cstring>

using namespace std;





const int N = 27;



typedef struct

{

    int in_degree;//记录入度

    int out_degree;//记录出度

}Point;



typedef struct

{

    int parent;

    int height;

}Node;



Point degree[N];

Node UFSet[N];

bool Visited[N];

int record[N], cnt;//此数组用于记录出现的字符





void init()

{//初始化入度和出度,初始化并查集

    int i;

    for(i = 0; i < N; i++)

    {

        degree[i].in_degree = degree[i].out_degree = 0;

        UFSet[i].parent = i;

        UFSet[i].height = 1;

        Visited[i] = false;

    }

    cnt = 0;

}



int find(int x)

{//并查集之查操作

    while(x != UFSet[x].parent)

        x = UFSet[x].parent;

    return x;

}



void merge(int x, int y)

{

    if(x == y)

        return ;

    if(UFSet[x].height == UFSet[y].height)

    {

        UFSet[y].parent = x;

        UFSet[x].height++;

    }

    else if(UFSet[x].height > UFSet[y].height)

        UFSet[y].parent = x;

    else

        UFSet[x].parent = y;

}



int main()

{

    int T;

    int n, a, b , i;

    int sum;

    bool flag;

    char str[1003];



    scanf("%d", &T);

    while(T--)

    {

        scanf("%d", &n);

        init();

        for(i = 0; i < n; i++)

        {

            scanf("%s", str);

            a = str[0] - 'a';

            b = str[strlen(str) - 1] - 'a';



            if(!Visited[a])

            {

                Visited[a] = true;

                record[cnt++] = a;

            }

            if(!Visited[b])

            {

                Visited[b] = true;

                record[cnt++] = b;

            }

            

            /**//////////入度,出度的统计///////////



            degree[b].in_degree++;

            degree[a].out_degree++;



            /**////////////并查集操作/////////

            a = find(a);

            b = find(b);

            merge(a, b);

        }

        

        flag = false;

        a = find(record[0]);



        for(i = 1; i < cnt; i++)

            if(a != find(record[i]))

            {

                flag = true;

                break;

            }



        if(flag)

        {//此为用并查集判连通

            printf("The door cannot be opened.\n");

            continue;

        }

        

        sum = a = b = 0; flag = true;

        for(i = 0; i < cnt && sum < 3; i++)

        {

            if(degree[record[i]].in_degree != degree[record[i]].out_degree)

            {

                sum++;



                if(degree[record[i]].in_degree ==  degree[record[i]].out_degree + 1)

                    a++;

                else if(degree[record[i]].in_degree + 1 ==  degree[record[i]].out_degree)

                    b++;

                else

                {

                    flag = false;

                    break;

                }

            }

        }



        if(flag && a == b)

            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、付费专栏及课程。

余额充值