ZOJ2016 POJ1386(有向图的欧拉路判断)


Play on Words

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 9710   Accepted: 3352

Description

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 Nthat indicates the number of plates (1 <= N <= 100000). Then exactly Nlines 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.

Source

Central Europe 1999

[Submit]   [Go Back]   [Status]  
[Discuss]

题意:

题目描述:

有些秘门带有一个有趣的词迷。考古学家必须解开词迷才能打开门。由于没有其他方法可以

打开门,因此词迷就变得很重要。

每个门上有许多磁盘。每个盘上有一个单词,这些磁盘必须重新排列使得每个单词第一个字

母跟前一个单词最后一个字母相同。例如单词"acm"可以跟在单词"motorola"的后面。你的任务是

编写一个程序,读入一组单词,然后判定是否可以经过重组使得每个单词第一个字母跟前一个单

词最后一个字母相同,这样才能打开门。

每个单词只有首尾两个字母很关键,并且每个单词可以看成连接首尾两个字母的一条有向边(由首字母指向尾字母)。这样每个测试数据中的一组单词可以构造成一个图:图中的顶点为 26 个小写字母,每个单词为图中的一条边。构造好有向图后,题目要判定是否可以经过重组使得每个单词第一个字母跟前一个单词最后一个字母相同,等效于判断图中是否存在一条路径经过每条边一次且仅一次,这就是有向欧拉通路。

#include <cstdio>
#include <cstring>
#include<vector>
#include<iostream>
using namespace std;
#define MAXN 100001
#define INF 100000000
char word[MAXN];
const int sz=30;
int p[sz],v[sz],in[sz],out[sz],E;
int G[sz][sz];
int findx(int x){
	return p[x]==x?x:p[x]=findx(p[x]);
}
void Union(int u,int v){
	p[findx(u)]=findx(v);
}
bool is_connect(){
	int x=0;
	for(int i=0;i<26;i++)if(v[i])
	{
		x=i;
		for(int j=0;j<26;++j)if(G[i][j]){
			Union(i,j);
		}
	}
	x=findx(x);
	for(int i=0;i<26;i++)if(v[i]){
		if(x!=findx(i))return false;
	}
	return true;
}
void AddEdge(int from,int to){
	v[from]=v[to]=1;
	if(from==to)return;
	G[from][to]=1;
	out[from]++;
	in[to]++;
}
void Init(){
	memset(in,0,sizeof in);
	memset(out,0,sizeof out);
	memset(v,0,sizeof v);
	memset(G,0,sizeof G);
	for(int i=0;i<26;i++)p[i]=i;
}
int main(int argc, char const *argv[])
{
	int T;
	scanf("%d",&T);
	while(T--){
		int n;
		scanf("%d",&n);
		bool ok=true;
		Init();
		while(n--){
			scanf("%s",word);
			AddEdge(word[0]-'a',word[strlen(word)-1]-'a');
		}
		int x1=0,x2=0;
		for(int i=0;i<26;i++)if(v[i]){
			if(out[i]-in[i]>1||in[i]-out[i]>1){
				ok=false;break;
			}else if(out[i]-in[i]==1){
				x1++;
				if(x1>1){
					ok=false;break;
				}
			}else if(out[i]+1==in[i]){
				x2++;
				if(x2>1){
					ok=false;break;
				}
			}

		}
		if(x1!=x2){
			ok=false;
		}if(ok&&!is_connect()) ok=false;
		puts(ok?"Ordering is possible.":"The door cannot be opened.");
	}
	return 0;
}
时间: 2024-10-27 08:29:17

ZOJ2016 POJ1386(有向图的欧拉路判断)的相关文章

POJ 2337 &amp;&amp; ZOJ 1919--Catenyms 【有向图 &amp;&amp; 欧拉路判断 &amp;&amp; 欧拉路径】

Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10427   Accepted: 2726 Description A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For

Play on Words UVA 10129 (有向图的欧拉路)

说说: 这道题的题意很简单,就是给你一些单词,问是否能形成一个句子,使前一个单词的最后一个字母等于后一个单词的第一个字母.本质上来说就是有向图的欧拉路问题,当然存在欧拉回路也是OK的.一开始的时候,我以为存在欧拉路只需判断两种情况:一,是存在欧拉回路,即每个节点的入度等于出度.二,存在欧拉路,有且仅有一个节点的入度比出度大一,一个节点的出度比入度大一.只要满足任意其中一种情况即可.事实上不是这样的,其实还需要判断该图是否连通.这自然而然就想到了并查集的思想.当出现两个节点的时候,将其中的一个节点

Play on Words HDU - 1116(欧拉路判断 + 并查集)

题意: 给出几个单词,求能否用所有的单词成语接龙 解析: 把每个单词的首字母和尾字母分别看作两个点u 和 v,输入每个单词后,u的出度++, v的入度++ 最后判断是否能组成欧拉路径 或 欧拉回路,当然首先要判断一下是否是一个连通块,用并查集维护就好了,当然有自环,所以用一个vis标记一下这个点是否出现过 看代码就懂了 #include <iostream> #include <cstdio> #include <sstream> #include <cstrin

POJ1386Play on Words[有向图欧拉路]

Play on Words Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11846   Accepted: 4050 Description Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because ther

欧拉路,欧拉回路小结(转)

欧拉路,欧拉回路小结 把欧拉路和欧拉回路做一个小总结,包含了一些题目,以后遇到新的我还会陆续加上. 定义: 给定无孤立结点图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在 一条回路经过G每条边有且仅有一次,称这条回路为欧拉回路.具有欧拉回路的图成为欧拉图. 关于欧拉路和欧拉回路定义及存在证明请看这里. 这里给出欧拉路和欧拉回路存在条件的结论: 存在欧拉路的条件: 无向图:  图连通,所有点都是偶数度,或者只有两个点是奇数度.当所有点是偶数度时欧拉路起点可以是任意 点:当

NYOJ 99单词拼接(有向图的欧拉(回)路)

1 /* 2 NYOJ 99单词拼接: 3 思路:欧拉回路或者欧拉路的搜索! 4 注意:是有向图的!不要当成无向图,否则在在搜索之前的判断中因为判断有无导致不必要的搜索,以致TLE! 5 有向图的欧拉路:abs(In[i] - Out[i])==1(入度[i] - 出度[i])的节点个数为两个 6 有向图的欧拉回路:所有的节点都有In[i]==Out[i] 7 */ 8 #include<iostream> 9 #include<cstring> 10 #include<cs

图论--欧拉路,欧拉回路(小结)

在题目中在慢慢细说概念 1.HDU - 3018 Ant Trip 题目大意:又N个村庄,M条道路,问需要走几次才能将所有的路遍历 解题思路:这题问的是有关欧拉路的判定 欧拉路就是每条边只能走一次,且要遍历所有的边,简单的说就是一笔画(图连通) 这道题是无向图的欧拉路,无向图的欧拉路的判定:所有点的度数都是偶数度,或者只有两个点的度是奇数度,且图要是连通图 知道欧拉路是什么后,这题就比较好做了,第一件事就是找到有几个连通块,然后再判断一下每个连通块需要几笔才能完成就好了 #include <cs

hiho 1182 : 欧拉路&amp;#183;三

1182 : 欧拉路·三 这时题目中给的提示: 小Ho:是这种.每次转动一个区域不是相当于原来数字去掉最左边一位,并在最后加上1或者0么. 于是我考虑对于"XYYY",它转动之后能够变成"YYY0"或者"YYY1".我就将全部的数字0~2^N-1看作2^N个点.连接全部的("XYYY","YYY0"),("XYYY","YYY1"). 比方当N=3时,我得到了这样一个

hiho 1182 : 欧拉路&#183;三

1182 : 欧拉路·三 这时题目中给的提示: 小Ho:是这样的,每次转动一个区域不是相当于原来数字去掉最左边一位,并在最后加上1或者0么. 于是我考虑对于"XYYY",它转动之后可以变成"YYY0"或者"YYY1".我就将所有的数字0~2^N-1看作2^N个点,连接所有的("XYYY","YYY0"),("XYYY","YYY1"). 比如当N=3时,我得到了这样一