Uva10129(欧拉回路)

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 ?rst line of the input ?le. 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 ?rst 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.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 const int maxn=26;
 5 using namespace std;
 6 /*
 7 欧拉回路
 8 图是否连通
 9 是否存在联通块1.并查集2.dfs
10 判断入度出度
11 */
12 int G[maxn][maxn],vis[maxn][maxn];
13 int n,m,in[maxn],out[maxn];
14 bool dfs(int u)
15 {
16     bool findd=false;//是否找到连通块
17     for(int v=0;v<maxn;v++)
18     {
19         if(G[u][v]&&!vis[u][v])//有边且没有被访问
20         {
21             vis[u][v]=vis[v][u]=1;
22             findd=true;
23             dfs(v);
24         }
25     }
26     return findd;
27 }
28 bool communication()
29 {
30     bool ok=false;//是否有连通块
31     for(int i=0;i<maxn;i++)
32     {
33         if(dfs(i))
34             {if(ok)
35             return false;//如果已有连通块,则图不连通
36             ok=true;
37             }
38     }
39     return true;
40 }
41 bool check()
42 {
43     bool innode=true;
44     bool outnode=true;
45     for(int i=0;i<maxn;i++)
46     {
47         if(in[i]==out[i])continue;//入度==出度
48         else if(in[i]-1==out[i]&&innode){//存在入度比出度大一,最多只能有一个这样的点
49             innode=false;
50             continue;
51         }
52         else if(out[i]-1==in[i]&&outnode){
53             outnode=false;
54             continue;
55         }
56         else
57             return false;
58     }
59     if(innode!=outnode)//两个点一个存在一个不存在,则不能构成欧拉回路
60         return false;
61     return true;
62 }
63 int main()
64 {
65     scanf("%d",&n);
66     while(n--)
67     {
68         scanf("%d",&m);
69         memset(vis,0,sizeof vis);
70         memset(G,0,sizeof G);
71         memset(in,0,sizeof in);
72         memset(out,0,sizeof out);
73         bool flag=true;
74         while(m--)
75         {
76             string a;
77             cin>>a;
78             int beginn=a[0]-‘a‘;
79             int endd=a[a.length()-1]-‘a‘;
80             in[beginn]++;
81             out[endd]++;
82             G[beginn][endd]=G[endd][beginn]=1;
83         }
84             if(communication())
85                 {
86                     if(!check())
87                         flag=false;
88                 }
89                 else flag=false;
90         if(flag)
91             printf("Ordering is possible.\n");
92         else printf("The door cannot be opened.\n");
93     }
94     return 0;
95 }

欧拉回路:该回路遍历了一个图中所有的边,并且每条边只遍历一次。(一笔画)

欧拉路径:从起点开始到终点,遍历了图中所有的边,并且每条边只遍历一次。

度数:一个点连接了几条边。

入度和出度分别指:进入该点的边的数量,走出该点的边的数量。

连通无向图存在欧拉回路的充要条件:所有点的度数都为偶数。

连通无向图存在欧拉路径的充要条件:仅存在两个度数为奇数的点,其他点的度数都为偶数。(这两个度数为奇数的点,一个为奇数,一个为偶数)

连通有向图存在欧拉回路的充要条件:对于所有的点,入度等于出度。

连通有向图存在欧拉路径的充要条件: 仅存在两个点,其中一个点的入度比出度大一,另一个店的出度比入度大一。(出度大的为起点,入度大的为终点)

根据连通性和度数可判断出无向图和有向图是否存在欧拉回路和欧拉路径,可用 dfs 构造欧拉回路和欧拉路径。

原文地址:https://www.cnblogs.com/zuiaimiusi/p/11072486.html

时间: 2024-11-12 15:04:16

Uva10129(欧拉回路)的相关文章

UVA10129: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. 一些密门会包含有趣的文字谜,考古学家小队为了开门不得不解决它.别无他法,

6_16 单词(UVa10129)&lt;欧拉回路&gt;

考古学家有时候遇到一些神秘的门,这些门需要解开特定的谜题才能打开.因为没有其他方法可以打开门,这谜题对我们来说非常重要.在门上有许多磁盘,每个盘子上有一个英文单字在上面.这些盘子必须被安排,使得盘子上的每个单字的第一个字母必须与前一个盘子的单字的最后一个字母相同.例如:acm后面可以接motorola.你的任务是写一个程序,读入所有的单字然后判断是否可以做出如上述的安排,如此来能打开门.Input输入的第一列有一个整数代表以下有几组测试数据.每组测试数据的第一列,有一个整数N(1 <= N <

[题解]UVA10129 Play on Words

链接:http://vjudge.net/problem/viewProblem.action?id=19492 描述:单词接龙 思路:求欧拉回路或欧拉道路. 首先建图,以字母为节点,单词为边.因为单词不可能倒序,所以是有向图. 判断图的连通性,dfs就可以做到,把它当成无向图就好了.然后判断点的出入度就可以判断是不是欧拉回路或者欧拉道路. 下面是我的实现. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstri

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

题目链接:https://vjudge.net/problem/UVA-10129 题目大意:输入N  代表有n个字符串  每个字符串最长1000  要求你把所有的字符串连成一个序列  每个字符串的第一个字母是前一个字符串的最后一个字母 思路:这是学的欧拉回路的第一道题 ,把单词的首字母和尾字母看做结点,单词看作边 ,判断能否找出一条欧拉回路就行了 首先要知道什么是欧拉回路: 第一个条件:图必须是连通的 第二个条件:最多只有两个奇点(出度和入度不相等的点) 满足上面两个条件的就是欧拉回路 如果有

混合图的欧拉回路判定

对于有向图和无向图的欧拉回路判定,很容易做到.那对于混合图呢?? 混合图就是图中既存在无向边又存在有向边的图. 至于解法: 转载自这里 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路.因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路. 好了,现在每个点入度和出度之差均为偶数.那么将这个偶数除以2,得x.也就是说,对于每一个点,只要将x条边改变方向(入>出就是变入,出>入就是变出),就能保证出 = 入.如果

hdu1116 欧拉回路

1 //Accepted 248 KB 125 ms 2 //欧拉回路 3 //以26个字母为定点,一个单词为从首字母到末尾字母的一条边 4 //下面就是有向图判断欧拉回路 5 //连通+节点入度和==出度和 或者 存在一对节点一个入度比出度大1,一个小1 6 #include <cstdio> 7 #include <cstring> 8 #include <iostream> 9 #include <queue> 10 using namespace s

POJ 1041 John&#39;s trip 无向图的【欧拉回路】路径输出

欧拉回路第一题TVT 本题的一个小技巧在于: [建立一个存放点与边关系的邻接矩阵] 1.先判断是否存在欧拉路径 无向图: 欧拉回路:连通 + 所有定点的度为偶数 欧拉路径:连通 + 除源点和终点外都为偶数 有向图: 欧拉回路:连通 + 所有点的入度 == 出度 欧拉路径:连通 + 源点 出度-入度=1 && 终点 入度 - 出度 = 1 && 其余点 入度 == 出度: 2.求欧拉路径 : step 1:选取起点(如果是点的度数全为偶数任意点为S如果有两个点的度数位奇数取一

寒假集训日志(二)——最小生成树,拓扑排序,欧拉回路,连通路

今天学的内容挺多的. (一)首先说最小生成树,两种算法: 1.Kruskal算法( 将边排序,然后再选,关键在于检查是否连通,使用并查集) 2.Prim算法(使用点集,有点类似与最短路的算法) 第一题是并查集算法的使用: A - The Suspects Time Limit:1000MS     Memory Limit:20000KB     64bit IO Format:%I64d & %I64u Submit Status Description 严重急性呼吸系统综合症( SARS),

HDU-1878 判断无向图欧拉回路,水

HDU 1878 题意:问一个无向图是否存在欧拉回路. 总结: 1.一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图.2.一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图.3.要判断一个混合图G(V,E)(既有有向边又有无向边)是欧拉图,方法如下:假设有一张图有向图G',在不论方向的情况下它与G同构.并且G'包含了G的所有有向边.那么如果存在一个图G'使得G'存在欧拉回路,那么G就存在欧拉回路. // HDU-1878 #include<bits/stdc++