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;
}

 

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