现在的位置: 首页 > 综合 > 正文

Play on Words 并查集加欧拉回路

2013年10月06日 ⁄ 综合 ⁄ 共 1097字 ⁄ 字号 评论关闭
//用并查集的时候先将当做无向图来处理判断图的连通性。
//然后用欧拉路的定义来求解。存在欧拉回路的条件是:所有点出度==入度。
//存在欧拉道路的条件是:有且仅有两个点出度!=入度,且出度和入度之差为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;
}

抱歉!评论已关闭.