UVa 10129 - Play on Words 欧拉道路

7 篇文章 0 订阅

Play on Words

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 Specification

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 exactlyNlines 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 Specification

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

32acmibm3acmmalformmouse2okok

Output for the Sample Input

The door cannot be opened.Ordering is possible.The door cannot be opened.

 

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int MAX = 26+5;

int g[MAX][MAX],in[MAX], out[MAX];
int vis[MAX];

void read()
{
	int n;
	char s[1100];
	cin >> n;
	for(int i=0; i < n; i++)
	{
		scanf("%s",s);
		int u =s[0]-'a';
		int v =s[strlen(s)-1]-'a';
		in[u]++;
		out[v]++;
		g[u][v] = g[v][u]= 1;
	}
}
// 判断是否是通路
void dfs(int u)
{
	for(int v=0; v < 26; v++)
	{
		if(g[u][v] && !vis[v])
		{
			vis[v] = 1;
			dfs(v);
		}
	}
}

bool cycle()
{
	int count=0;
	for(int i=0; i < 26; i++)
	{
		if(in[i] || out[i])
			if(!vis[i])
			{
				vis[i] = 1;
				count++;
				dfs(i);
			}
	}
	
	// 多于一个强联通分量
	if(count>1)
		return false;
	return true;
}
// 欧拉道路的性质
bool euler()
{
	int a=0, b=0;
	for(int i=0; i < 26; i++)
	{
		if(in[i]-out[i]==1)
		{
			a++;
			if(a>1)
				return false;
		}else if(out[i]-in[i]==1)
		{
			b++;
			if(b>1)
				return false;
		}else if(in[i]!=out[i]){
			return false;
		}
	}
	return true;
}

void init()
{
	memset(g, 0, sizeof(g));
	memset(in, 0, sizeof(in));
	memset(out, 0, sizeof(out));
	memset(vis, 0, sizeof(vis));
}

int main()
{
//	freopen("in.txt","r",stdin);
	int nCase;
	cin >> nCase;
	while(nCase--)
	{
		init();
		read();
		if(cycle())
		{
			if(euler())
				cout << "Ordering is possible." << endl;
			else
				cout << "The door cannot be opened." << endl;
		}else
			cout <<"The door cannot be opened." << endl;
	}
	return 0;
}

欧拉回路和路径一些问题:

连通的无向图 G 有欧拉路径的充要条件是:G中奇顶点(连接的边数量为奇数的顶点)的数目等于0或者2。

连通的无向图 G 是欧拉(存在欧拉回路)的充要条件是:G中每个顶点的度都是偶数。

证明
  • 必要性:如果一个图能一笔画成,那么对每一个顶点,要么路径中“进入”这个点的边数等于“离开”这个点的边数:这时点的度为偶数,要么两者相差一:这时这个点必然是起点或终点之一。注意到有起点就必然有终点,因此奇顶点的数目要么是0,要么是2。
  • 充分性:
    1. 如果图中没有奇顶点,那么随便选一个点出发,连一个环C_1。如果这个环就是原图,那么结束。如果不是,那么由于原图是连通的,C_1 和原图的其它部分必然有公共顶点 s_1。从这一点出发,在原图的剩余部分中重复上述步骤。由于原图是连通图,经过若干步后,全图被分为一些环。由于两个相连的环就是一个环,原来的图也就是一个欧拉环了。
    2. 如果图中有两个奇顶点 uv,那么加多一条边将它们连上后得到一个无奇顶点的连通图。由上知这个图是一个环,因此去掉新加的边后成为一条路径,起点和终点是 uv。证毕。

连通无向图有欧拉路径的充要条件也可以写作“图中奇顶点数目不多于2个”,这是因为奇顶点数目不可能是1个。实际上,连通无向图中,奇顶点的数目总是偶数。

对于不连通的无向图,如果有两个互不连通的部分都包含至少一条边,那么显然不能一笔画。只有当此图的边全都在某一个连通部分中(即其它的连通部分都是一个个孤立的顶点,度数为0),并满足连通无向图关于一笔画的充要条件,而该图才能一笔画。也即是说,可以一笔画的(无向)图如果不是连通图,就必定是一个可以一笔画的连通图与若干个孤立顶点的组合。

除了用顶点的度数作为判定的充要条件,还可以用图中边的特性来作为欧拉回路存在的判定准则。连通的无向图 G中存在欧拉回路,等价于图G所有的边可以划分为若干个环的不交并。具体来说,等价于存在一系列的环C_1, C_2 , \cdots , C_m,使得图G里的每一条边都恰好属于某一个环。


1.对于上题中的在判断是否符合欧拉路径的时候用到了3个条件,

一是存在一个点入度减去出度为1,即终点, 

二.出度减去入度为1,即起点。

三. 其余的点都是出度等于入度 



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值