Play on Words UVA - 10129 (欧拉回路)

题目:

Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other way to open the doors, the puzzle is very important for us.

There is a large number of magnetic plates on every door. Every plate has one word written on it. The plates must be arranged into a sequence in such a way that every word begins with the same letter as the previous word ends.

For example, the word ‘acm’ can be followed by the word ‘motorola’. Your task is to write a computer program that will read the list of words and determine whether it is possible to arrange all of the plates in a sequence (according to the given rule) and consequently to open the door.

Input

The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing a single integer number N that indicates the number of plates (1 ≤ N ≤ 100000). Then exactly N lines follow, each containing a single word. Each word contains at least two and at most 1000 lowercase characters, that means only letters ‘a’ through ‘z’ will appear in the word. The same word may appear several times in the list.

Output

Your program has to determine whether it is possible to arrange all the plates in a sequence such that the first letter of each word is equal to the last letter of the previous word. All the plates from the list must be used, each exactly once. The words mentioned several times must be used that number of times.

If there exists such an ordering of plates, your program should print the sentence ‘Ordering is possible.’. Otherwise, output the sentence ‘The door cannot be opened.’

Sample Input

3

2

acm

ibm

3

acm

malform

mouse

2

ok

ok

Sample Output

The door cannot be opened.

Ordering is possible.

The door cannot be opened.

题意:

给你两个数字  t,n,代表有t组测试数据,每一组测试数据有一个数字n代表有n组单词,且单词全是小写字母;

让你把这些单词连接起来(首尾字母相同才可以连接起来);

如果能够连接起来就输出:Ordering is possible.

否则输出: The door cannot be opened.

思路:

这道题可以用并查集来判断图是否连通,但是想做出来这道题还有知道什么是欧拉回路。

欧拉回路: 通过图中每条边且只通过一次,并且经过每一顶点的回路。

有向欧拉回路的特点:D为有向图,D的基图连通,并且所有顶点的出度与入度相等;或者  除两个顶点外,其余顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度与入度之差为-1。

那么在做这道题的时候,我们知道单词的连接只和首尾的字母有关系,那么我们直接把字母转换成数字进行存储,转换成一个有向图进行存储;

我们可以通过并查集来判断图的连通性;

是否是一个欧拉回路,那么我们就按照欧拉回路的要求来判断,判断每一个点的出度和入度,判断起始顶点和结束定点的出度和入度之间的关系;

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
/*
有向图D存在欧拉通路的充要条件是:
D为有向图,D的基图连通,并且所有顶点的出度与入度相等;
或者  除两个顶点外,其余顶点的出度与入度都相等,
而这两个顶点中一个顶点的出度与入度之差为1,
另一个顶点的出度与入度之差为-1.
*/
int pre[30];//父亲节点;
int que[30];//出现的次数;
int in[30];//入度;
int out[30];//出度;

void init()//初始化;
{
    memset(pre,-1,sizeof pre);
    memset(que,0,sizeof que);
    memset(in,0,sizeof in);
    memset(out,0,sizeof out);
}

int find(int x)//寻找父亲节点;
{
    return pre[x]=x==pre[x]?x:find(pre[x]);
}

void merge(int x,int y)//合并;
{
    int f1,f2;
    if(pre[x]==-1)
        pre[x]=x;
    if(pre[y]==-1)
        pre[y]=y;
    f1=find(x);
    f2=find(y);
    if(f1!=f2)
        pre[f1]=f2;
    return;
}

int main()
{
    int T,N,a,b;
    char s[1010];
    scanf("%d",&T);
    while(T--)
    {
        init();//初始化;
        scanf("%d",&N);
        for(int i=0; i<N; i++)
        {
            scanf("%s",s);
            a=s[0]-'a';//转换成数字;
            b=s[strlen(s)-1]-'a';
            que[a]++;
            que[b]++;
            in[a]++;//入度;
            out[b]++;//出度;
            merge(a,b);//合并;
        }
        int flot=0,cnt=0,ok=1,x1=0,x2=0;
        for(int i=0; i<26; i++)
        {
            if(pre[i]==-1)
                continue;
            if(que[i]%2==1)//度数为奇数的顶点的个数;
                cnt++;
            if(pre[i]==i)//是否连通,如果联通,那么久会只有一个块;
                flot++;
            if(abs(in[i]-out[i])>=2)//出入度之差
                ok=0;
        }//注意要判断入度出度差不能大于等于2;
        //两个顶点的出入度之差的差是2,别的定点出入度相等;
        if(ok&&flot==1&&(cnt==0||cnt==2))
            printf("Ordering is possible.\n");
        else
            printf("The door cannot be opened.\n");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章