【思维题 欧拉图】loj#10106. 单词游戏
巧妙的模型转化
题目描述
来自 ICPC CERC 1999/2000,有改动。
有 NNN 个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子中,前一个盘子上单词的末字母等于后一个盘子上单词的首字母。请你编写一个程序,判断是否能达到这一要求。如果能,请给出一个合适的顺序。
输入格式
多组数据。第一行给出数据组数 TTT,每组数据第一行给出盘子数量 NNN,接下去 NNN 行给出小写字母字符串,一种字符串可能出现多次。
输出格式
若存在一组合法解输出Ordering is possible.,否则输出The door cannot be opened.。
题目分析
看到题最自然的想法当然是求哈密尔顿路。然而哈密尔顿路并没有什么好的性质,所以考虑另一种建模:欧拉图。
每一个单词有用的信息只有首尾两个字母,那么建一张图令节点表示小写字母;边表示一种单词的转移。问题就变成了在图中判断欧拉路径的存在性。
若有向图G存在欧拉路径(即为半欧拉图),那么当且仅当G的基图联通且存在顶点$u$的入度比出度大1,$v$的入度比出度小1,其他所有顶点的入度等于出度。
代码内有些处理细节的精妙之处。
#include<bits/stdc++.h> int T,n,m;
char s[];
int fa[],u[],v[],cnt,cnt1,cnt2; int get(int x){return x==fa[x]?x:fa[x]=get(fa[x]);}
int abs(int a){return a>?a:-a;}
int main()
{
scanf("%d",&T);
while (T--)
{
memset(u, , sizeof u);
memset(v, , sizeof v);
scanf("%d",&n);
cnt = cnt1 = cnt2 = ;
for (int i=; i<=; i++) fa[i] = i;
for (int i=; i<=n; i++)
{
scanf("%s",s+), m = strlen(s+);
int l = s[]-'a'+, r = s[m]-'a'+;
fa[get(l)] = get(r), u[l]++, v[r]++;
}
for (int i=; i<=; i++)
if (((u[i]||v[i])&&(get(i)==i))||abs(u[i]-v[i]) > ) cnt++;
//连通块个数的统计 //出入度不相等的点个数
if (cnt > ){
puts("The door cannot be opened.");
continue;
}
for (int i=; i<=; i++)
if (u[i] > v[i]) cnt1++;
else if (u[i] < v[i]) cnt2++;
if (cnt1!=cnt2||cnt1 > )
puts("The door cannot be opened.");
else puts("Ordering is possible.");
}
return ;
}
END
【思维题 欧拉图】loj#10106. 单词游戏的更多相关文章
- 洛谷P4643 [国家集训队]阿狸和桃子的游戏(思维题+贪心)
思维题,好题 把每条边的边权平分到这条边的两个顶点上,之后就是个sb贪心了 正确性证明: 如果一条边的两个顶点被一个人选了,一整条边的贡献就凑齐了 如果分别被两个人选了,一作差就抵消了,相当于谁都没有 ...
- Luogu P1278 单词游戏(dfs)
P1278 单词游戏 题意 题目描述 \(Io\)和\(Ao\)在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何 ...
- Xor 思维题
Xor 思维题 题目描述 小\(Q\)与小\(T\)正在玩一棵树.这棵树有\(n\)个节点,编号为 \(1\),\(2\) \(3...n\),由\(n-1\)条边连接,每个节点有一个权值\(w_i\ ...
- POJ C程序设计进阶 编程题#1:单词翻转
编程题#1:单词翻转 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 输入一 ...
- zoj 3778 Talented Chef(思维题)
题目 题意:一个人可以在一分钟同时进行m道菜的一个步骤,共有n道菜,每道菜各有xi个步骤,求做完的最短时间. 思路:一道很水的思维题, 根本不需要去 考虑模拟过程 以及先做那道菜(比赛的时候就是这么考 ...
- cf A. Inna and Pink Pony(思维题)
题目:http://codeforces.com/contest/374/problem/A 题意:求到达边界的最小步数.. 刚开始以为是 bfs,不过数据10^6太大了,肯定不是... 一个思维题, ...
- ZOJ 3829 贪心 思维题
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829 现场做这道题的时候,感觉是思维题.自己智商不够.不敢搞,想着队友智商 ...
- C. Nice Garland Codeforces Round #535 (Div. 3) 思维题
C. Nice Garland time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- PJ考试可能会用到的数学思维题选讲-自学教程-自学笔记
PJ考试可能会用到的数学思维题选讲 by Pleiades_Antares 是学弟学妹的讲义--然后一部分题目是我弄的一部分来源于洛谷用户@ 普及组的一些数学思维题,所以可能有点菜咯别怪我 OI中的数 ...
随机推荐
- EF下使用自定义的connectionString避免数据库密码泄露
在使用EF框架时,缺省情况下数据库访问字串是明码存放在app.config或web.config中的,相当于让数据库裸奔. 实际上EF在创建数据实体时,可以指定连接字串,取代在app.config中读 ...
- 已知单链表的数据元素为整型数且递增有序,L为单链表的哨兵指针。编写算法将表中值大于X小于Y的所有结点的顺序逆置。(C语言)
对此题目的完整示例可直接运行代码如下: #include <stdio.h> #include <stdlib.h> typedef struct LNode{ int dat ...
- Java中对象拷贝的两种方式
引用的拷贝 //引用拷贝 private static void copyReferenceObject(){ Person p = new Person(23, "zhang") ...
- edge 浏览器自动识别电话号码解问题解决方法
解决方案:再head中加上: <meta name="format-detection" content="telephone=no">
- Vnc在Ubuntu14.04上的安装和配置 安装:
安装: Ubuntu14.04 : sudo apt-get install vnc4server : sudo apt-get install xrdp iPad : 安装 vnc viewer 或 ...
- Unity3d网格合并
几个不同的物体,在Unity3d中可以将网格合并在一起,用于优化. 在Unity3d中构建临时场景如下:建一C#脚本名为"CombineMeshes",挂在Cube上. Combi ...
- 洛谷 P1807 最长路_NOI导刊2010提高(07)
最长路 #include <iostream> #include <cstdio> #include <cstring> #include <queue> ...
- 零基础逆向工程20_PE结构04_任意节空白区_新增节_扩大节添加代码
向代码节添加代码实现 作者经过一周不断的失败,再思考以及无数次调试终于实现. 思路:八个步骤 1. 文件拷到文件缓冲区(FileBuffer) //图示见(零基础逆向工程18之PE加载过程) 2. 文 ...
- typedef int status
是个自定义类型的语句,typedef用来定义类型的别名,status i 就相当于int i
- winform ListView创建columnHeader的方法
using System; using System.Windows.Forms; using System.Drawing; using System.Collections; namespace ...