hdu1116 Play on Words--并查集
原题链接: pid=1116">http://acm.hdu.edu.cn/showproblem.php? pid=1116
一:原题内容
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.
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.
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.".
3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok
The door cannot be opened.
Ordering is possible.
The door cannot be opened.
二:分析理解
题目大意:给你一些英文单词。推断全部单词能不能连成一串,类似成语接龙的意思。
可是假设有多个反复的单词时,也必须满足这种条件才干算YES。
否则都是不可能的情况。
解题思路:欧拉路的基本题。仅仅要知道就能够做出来了。
关于欧拉回路和欧拉路径
定义:
欧拉回路:每条边恰好仅仅走一次。并能回到出发点的路径
欧拉路径:经过每一条边一次。可是不要求回到起始点
①首先看欧拉回路存在性的判定:
一、无向图
每一个顶点的度数都是偶数,则存在欧拉回路。
二、有向图(全部边都是单向的)
每一个节顶点的入度都等于出度,则存在欧拉回路。
三.混合图欧拉回路
混合图欧拉回路用的是网络流。
把该图的无向边随便定向,计算每一个点的入度和出度。假设有某个点出入度之差为奇数,那么肯定不存在欧拉回路。由于欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路。
好了,如今每一个点入度和出度之差均为偶数。
那么将这个偶数除以2。得x。也就是说。对于每一个点,仅仅要将x条边改变方向(入>出就是变入,出>入就是变出),就能保证出 = 入。假设每一个点都是出 = 入。那么非常明显。该图就存在欧拉回路。
如今的问题就变成了:我该改变哪些边,能够让每一个点出 = 入?构造网络流模型。首先,有向边是不能改变方向的,要之无用。删。
一開始不是把无向边定向了吗?定的是什么向,就把网络构建成什么样。边长容量上限1。另新建s和t。对于入 > 出的点u,连接边(u, t)、容量为x。对于出 > 入的点v,连接边(s, v),容量为x(注意对不同的点x不同)。
之后。察看是否有满流的分配。有就是能有欧拉回路。没有就是没有。
欧拉回路是哪个?查看流值分配,将全部流量非 0(上限是1,流值不是0就是1)的边反向,就能得到每点入度 =
出度的欧拉图。
因为是满流,所以每一个入 > 出的点,都有x条边进来,将这些进来的边反向。OK,入 = 出了。对于出 > 入的点亦然。
那么。没和s、t连接的点怎么办?和s连接的条件是出 > 入,和t连接的条件是入 > 出,那么这个既没和s也没和t连接的点。自然早在開始就已经满足入 = 出了。那么在网络流过程中,这些点属于“中间点”。
我们知道中间点流量不同意有累积的。这样。进去多少就出来多少,反向之后,自然仍保持平衡。
所以,就这样。混合图欧拉回路问题,解了。
②.欧拉路径存在性的判定
一。无向图
一个无向图存在欧拉路径。当且仅当 该图全部顶点的度数为偶数 或者 除了两个度数为奇数外其余的全是偶数。
二。有向图
一个有向图存在欧拉路径,当且仅当 该图全部顶点的度数为零 或者 一个顶点的度数为1,还有一个度数为-1,其它顶点的度数为0。
三。混合图欧拉路径
事实上整篇文章仅仅有这部分是我写的哈,灰常不好意思。仅仅是网上的同志们写的太好了。实在没有必要反复劳动,不知道大家有没有发现。求欧拉路径的第一步一定是求欧拉回路。在混合图上也不例外,怎样推断混合图欧拉回路问题的存在性呢?首先。我们用上文所说的方法推断该图是否存在欧拉回路,假设存在。欧拉路径一定存在。假设欧拉回路不存在,那么我们枚举欧拉路径的起点和终点,连接一条无向边。然后再用最大流推断是否存在欧拉回路就可以。
所以这道题的大题思路就是:
1.并查集推断连通
2.将每一个单词取出首字母和尾字母,转换为一条边,然后增加相应的连通分量中。
假设这个字母出现过。visit数组标记为true。同一时候起点出度加1。终点入度加1.
3.推断一下:
1)这个图必须是连通的,即根结点仅仅有一个。假设不是,直接结束本次算法。
2)假设这个图是连通的。推断每一个结点的入度和出度情况。
假设这个图是欧拉路,则每一个顶点的出度等于入度。
即out[i] = in[i]
假设这个图是半欧拉图。则起点的出度比入度大1。终点的入度比出度大1.其余顶点的出度等于入度。
假设满足上述条件,就能够将全部单词链接起来,否则不能。
当然。在推断出度入度的时候另一点须要注意,那就是除了起点终点以外的顶点。出度必须等于入度(出度入度能够同一时候为2。即环),可是起点和终点必须保证出度和入度之差为1。
三:AC代码
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #include<iostream>
#include<string.h> using namespace std; char ch[1001]; //存储单词
int pre[27]; //一共26个英文字母。下标从1開始,用于并查集
int in[27]; //表示每一个单词的尾部字母的入度,默认是0
int out[27]; //表示每一个单词的头部字母的出度。默认是0
bool visited[27]; //字母是否出现。默认是false
int T; //測试实例个数
int N; //每一个实例要输入的单词的个数
int inNum; //推断出现的全部的字母,“入度减出度为1”的个数
int outNum; //推断出现的全部的字母,“出度减入度为1”的个数
int root; //根节点个数
bool flag; //推断出现的全部的字母的出度和入度之差是否是0或1,假设不是。那肯定不满足题意,还有推断root是否大于1,大于1的话。肯定不满足
int start;
int last; int Find(int x)
{
return (x != pre[x]) ? Find(pre[x]) : x;
} void Union(int x, int y)
{
int root_x = Find(x);
int root_y = Find(y); if (root_x != root_y)
pre[root_x] = root_y;
} int main()
{
cin >> T;
while (T--)
{
for (int i = 1; i < 27; i++)
pre[i] = i;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(visited, 0, sizeof(visited)); inNum = outNum = root = 0;
flag = true; cin >> N;
for (int i = 0; i < N; i++)
{
cin >> ch;
int len = strlen(ch); start = ch[0] - 'a' + 1;
last = ch[len - 1] - 'a' + 1; visited[start] = true;
visited[last] = true;
out[start]++;
in[last]++; Union(start, last);
} for (int i = 1; i <= 26; i++)
{
if (visited[i])
{
if (pre[i] == i)
root++;
if (out[i] != in[i])//注意点
{
if (out[i] - in[i] == 1)
outNum++;
else if (in[i] - out[i] == 1)
inNum++;
else
flag = false;
}
} if (!flag)
break;
if (root > 1)
{
flag = false;
break;
}
} if ((flag&&inNum == 0 && outNum == 0) || (flag&&inNum == 1 && outNum == 1))
cout << "Ordering is possible.\n";
else
cout << "The door cannot be opened.\n";
} return 0;
}
參考 :http://www.acmerblog.com/hdu-1116-play-on-words-1412.html
hdu1116 Play on Words--并查集的更多相关文章
- HDU1116(欧拉路径+并查集)
题意: 给出一些字符串,有这两个字符串,如果第一个字符串的最后一个字母和第二个字符串的第一个字母是一样的,则这两个字符串是可以连接在一起的. 问给出的这些字符串能否串成一个环或者一整个链. 思路: 将 ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- bzoj1854--并查集
这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- Codeforces 731C Socks 并查集
题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...
随机推荐
- Unity实现屏幕抖动效果(通过Camera Viewpoint实现)
由于游戏死亡时一般都需要屏幕抖一下下. 所以百度了下相关写法,发现方法很多~~~ 找来找去,找到个简单粗暴地,啥都不需要,一个脚本拖动到Camera上就可以了 略微修改了一点点,share一下 usi ...
- [ Luogu Contest 10364 ] TG
\(\\\) \(\#A\) 小凯的数字 给出两个整数\(L,R\),从\(L\)到\(R\)按顺序写下来,求生成整数对\(9\)取模后的答案. 例如\(L=8,R=12\),生成的数字是\(8910 ...
- 表格对象的获取和更改(原生js)
表格对象的获取 var oT = document.getElementById("tb"); //获取head console.log(oT.tHead); console.lo ...
- Android项目实战_手机安全卫士软件管家
###1.应用程序信息的flags 1. int flags = packageInfo.applicationInfo.flags2. 0000 0000 0000 0000 0000 0000 0 ...
- jQuery——自定义动画
动画方法:animate(json,1000, function (){}) 参数说明:json代表属性设置,1000是动画时间,最后一个是回调函数,其中动画时间可选 属性支持:http://www. ...
- Java编译器、JVM、解释器
Java虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该系统上运行.本文首先简要介绍从Java文件的编译 ...
- Java多线程学习笔记(三)——Future和FutureTask
Future接口:它是对于具体的Runnable或者Callable任务的执行结果进行取消.查询是否完成.获取结果.必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果. 接口中有5中方 ...
- 解决 i5 6500 安装黑苹果 Sierra 显卡不正常问题
i5 6500内置HD 530显卡,装好Sierra显卡驱动不太正常. 先下载Clover configurator 用Clover configurator加载 EFI (Mount EFI)分区 ...
- css页面布局总结
W3C标准:是万维网制定的一系列标准,包括结构化标准语言(html.xml),表现 标准语言(css),行为标准语言(DOM,ECMAScript<javascript>)组成.这个标准倡 ...
- 基于owncloud构建私有云储存网盘
注意事项:需要ping通外网 需要LAMP架构yum -y install httpd php php-mysql mariadb-server mariadb sqlite php-dom php- ...