HDU 1116 Play on Words(有向图的欧拉路)

题目链接

首先这个题,我以为是DFS。。。交上各种TLE ,RE,暴栈和超时啊。。。找了一下题解,发现是图论问题。。。唉。

又重新翻离散课本。。。定理:有向图的欧拉路连通且存在一个出度比入度大一的,存在一个入度比出度大一的,其他入度出度相等。有向图欧拉回路连通且入度出度都相等。

交上WA,然后查错,总以为是 判断是否是联通的时候做错了,其实是 忘记判断也是欧拉回路了。。。悲剧。。。代码  好烂。

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int p[27][27],z,n,o[27],key[27];

int find(int x)

{

    int r,t;

    r = x;

    while(x != o[x])

    x = o[x];

    while(r != x)

    {

        t = o[r];

        o[r] = x;

        r = t;

    }

    return x;

}

void merge(int x,int y)

{

    x = find(x);

    y = find(y);

    if(x != y)

    o[x] = y;

}

int main()

{

    int t,i,j,sum,start,end,len,sum1,sum2,k1,k2;

    char str[1001];

    scanf("%d%*c",&t);

    while(t--)

    {

        z = 1;k1 = k2 = 0;

        memset(p,0,sizeof(p));

        memset(key,0,sizeof(key));

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

        o[i] = i;

        scanf("%d%*c",&n);

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

        {

            scanf("%s",str);

            len = strlen(str);

            start = str[0] - 'a'+1;

            end = str[len-1] - 'a'+1;

            key[start] = key[end] = 1;

            merge(start,end);

            p[start][end] ++;

        }

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

        {

            if(key[i])

            break;

        }

        sum = find(i);

        for(j = i+1;j <= 26;j ++)

        {

            if(find(j) != sum && key[j])

            break;

        }

        if(j != 27)

        z = 0;

        for(i = 1;i <= 26&&z;i ++)

        {

            sum1 = sum2 = 0;

            for(j = 1;j <= 26;j ++)

            {

                sum1 += p[i][j];

                sum2 += p[j][i];

            }

            if(sum1 == sum2)

            ;

            else if(sum1 == sum2+1)

            {

                k1++;

            }

            else if(sum1+1 == sum2)

            {

                k2 ++;

            }

            else

            {

                z = 0;

                break;

            }

        }

        if(z)

        {

            if(k1==1&&k2==1)

            printf("Ordering is possible.\n");

            else if(k1==0&&k2==0)

            printf("Ordering is possible.\n");

            else

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

        }

        else

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

    }

    return 0;

}

你可能感兴趣的:(word)