题目大意:给出一系列单词,当某个单词的首字母和前一个单词的尾字母相同,则这两个单词能链接起来。给出一系列单词,问是否能够连起来。

题目分析:以单词的首尾字母为点,单词为边建立有向图,便是判断图中是否存在欧拉道路。有向图中存在欧拉路径的两个条件是:1、忽略边的方向性后,底图联通;2、奇点个数为0时、奇点个数为2并且满足起点的入度比出度小1和终点的出度比入度大1时,欧拉道路一定存在;

判断图的连通性有两种方法:1、利用并查集,只判断有几个根节点即可;2、使用DFS,做法实质上就是判断联通块的个数;

利用并查集:

# include<iostream>
# include<cstdio>
# include<map>
# include<set>
# include<string>
# include<cstring>
# include<algorithm>
using namespace std; int n,in[26],out[26],fa[26],mark[26];
char p[1005]; int fin(int u)
{
int x=u;
while(fa[u]!=u)
u=fa[u];
while(fa[x]!=u){
int k=fa[x];
fa[x]=u;
x=k;
}
return u;
} int get()
{
int cnt=0;
for(int i=0;i<26;++i)
if(mark[i]&&fa[i]==i)
++cnt;
return cnt;
} bool judge()
{
if(get()>1)
return false; int cnt=0;
for(int i=0;i<26;++i)
if(mark[i]&&in[i]!=out[i])
++cnt;
if(cnt>2)
return false;
if(cnt==0)
return true;
if(cnt==1)
return false; int k1=0,k2=0;
for(int i=0;i<26;++i){
if(mark[i]&&in[i]!=out[i]){
if(in[i]+1==out[i])
k1=1;
if(in[i]==out[i]+1)
k2=1;
}
}
return k1&&k2;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(mark,0,sizeof(mark));
for(int i=0;i<26;++i) fa[i]=i;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%s",p);
int l=strlen(p);
mark[p[0]-'a']=mark[p[l-1]-'a']=1;
++out[p[0]-'a'];
++in[p[l-1]-'a'];
int u=fin(p[0]-'a');
int v=fin(p[l-1]-'a');
if(u!=v)
fa[u]=v;
}
if(judge())
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
return 0;
}

  

使用DFS:

# include<iostream>
# include<cstdio>
# include<map>
# include<set>
# include<string>
# include<cstring>
# include<algorithm>
using namespace std; int n,in[26],out[26],mark[26],vis[26],mp[26][26];
char p[1005]; void dfs(int u)
{
for(int i=0;i<26;++i){
if(mark[i]&&!vis[i]&&mp[u][i]){
vis[i]=1;
dfs(i);
}
}
} bool judge()
{
int cnt=0;
memset(vis,0,sizeof(vis));
for(int i=0;i<26;++i){
if(mark[i]&&!vis[i]){
++cnt;
vis[i]=1;
dfs(i);
}
}
if(cnt>1)
return false; for(int i=0;i<26;++i)
if(mark[i]&&vis[i]==0)
return false; cnt=0;
for(int i=0;i<26;++i)
if(mark[i]&&in[i]!=out[i])
++cnt;
if(cnt>2)
return false;
if(cnt==0)
return true;
if(cnt==1)
return false; int k1=0,k2=0;
for(int i=0;i<26;++i){
if(mark[i]&&in[i]!=out[i]){
if(in[i]+1==out[i])
k1=1;
if(in[i]==out[i]+1)
k2=1;
}
}
return k1&&k2;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(in,0,sizeof(in));
memset(mp,0,sizeof(mp));
memset(out,0,sizeof(out));
memset(mark,0,sizeof(mark));
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%s",p);
int l=strlen(p);
mp[p[0]-'a'][p[l-1]-'a']=mark[p[0]-'a']=mark[p[l-1]-'a']=1;
++out[p[0]-'a'];
++in[p[l-1]-'a'];
} if(judge())
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
return 0;
}

  

UVA-10129 Play on Words (判断欧拉道路的存在性)的更多相关文章

  1. UVa 10129 Play On Words【欧拉道路 并查集 】

    题意:给出n个单词,问这n个单词能否首尾接龙,即能否构成欧拉道路 按照紫书上的思路:用并查集来做,取每一个单词的第一个字母,和最后一个字母进行并查集的操作 但这道题目是欧拉道路(下面摘自http:// ...

  2. UVA 10129 Play on Words(欧拉道路)

    题意:给你n个字符串,问你是否可以出现一条链,保证链中每个字符串的第一个元素与上一个字符串的最后一个元素相同,注意可能重复出现同一个字符串 题解:以每一个字符串第一个元素指向最后一个元素形成一个有向图 ...

  3. Uva 10129 - Play on Words 单词接龙 欧拉道路应用

    跟Uva 10054很像,不过这题的单词是不能反向的,所以是有向图,判断欧拉道路. 关于欧拉道路(from Titanium大神): 判断有向图是否有欧拉路 1.判断有向图的基图(即有向图转化为无向图 ...

  4. UVA 10441 - Catenyms(欧拉道路)

    UVA 10441 - Catenyms 题目链接 题意:给定一些单词,求拼接起来,字典序最小的,注意这里的字典序为一个个单词比过去,并非一个个字母 思路:欧拉回路.利用并查集判联通,然后欧拉道路判定 ...

  5. 【UVa】12118 Inspector's Dilemma(欧拉道路)

    题目 题目     分析 很巧秒的一道题目,对着绿书瞎yy一会. 联一下必须要走的几条边,然后会形成几个联通分量,统计里面度数为奇数的点,最后再减去2再除以2.这样不断相加的和加上e再乘以t就是答案, ...

  6. Nyoj42 一笔画问题 (欧拉道路)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=42题目链接 #include <cstdio> #include <cstring ...

  7. POJ 2513 Colored Sticks(欧拉道路+字典树+并查集)

    http://poj.org/problem?id=2513 题意: 给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的. 思路: 题目很明 ...

  8. UVA10129———欧拉道路

    题目 输入n(n≤100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同(例如 acm,malform,mouse).每个单词最多包含1000 ...

  9. poj2480(利用欧拉函数的积性求解)

    题目链接: http://poj.org/problem?id=2480 题意:∑gcd(i, N) 1<=i <=N,就这个公式,给你一个n,让你求sum=gcd(1,n)+gcd(2, ...

随机推荐

  1. CH1402 后缀数组【Hash】【字符串】【二分】

    1402 后缀数组 0x10「基本数据结构」例题 描述 后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者DC3算法实现,这超出了我们的讨论范围.在本题中,我们希望使用快排.Hash与二分实现 ...

  2. python的tqdm模块

    Tqdm 是一个快速,可扩展的Python进度条,可以在 Python 长循环中添加一个进度提示信息,用户只需要封装任意的迭代器 tqdm(iterator). 根据要求安装依赖即可. 可以很方便的在 ...

  3. beans有无状态

    Spring Bean Scopes https://www.tutorialspoint.com/spring/spring_bean_scopes.htm When defining a < ...

  4. The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path(Myeclipse添加Server Library)

    网上找练习的项目导入到myeclipse项目发现每个JSP 出现错误The superclass "javax.servlet.http.HttpServlet" was not ...

  5. docker网络部分源码分析

    daemon初始化network controller daemon的配置,网络部分的内容在cmd/dockerd/config_common_unix.go中指定,默认设置一般都为空 // daem ...

  6. importlib模块与__import__详解

    importlib模块与__import__都可以通过过字符串来导入另外一个模块,但在用法上和本质上都有很大的不同. 通过下面示例说明,有如下一个工程目录: name = 'test' def get ...

  7. DIY自己的GIS程序(1)——起航

    一个GIS系统最重要的功能是绘制图形和关联属性,这里研究二维点线面的绘制过程: 对于一个绘图系统设计,图形的绘制涉及两个重要的方面. 1.一个是绘制或者重新绘制,重绘过程出现在下面情况: a 界面初始 ...

  8. c#将十进制转64进制

    //由于用于文件命名,所以将64位中的+转换为=,/转换为_     static char[] digits = {          '0' , '1' , '2' , '3' , '4' , ' ...

  9. 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution

    A - Odd Palindrome 水. #include <bits/stdc++.h> using namespace std; #define N 110 char s[N]; i ...

  10. Tcp/Ip:Telnet指令

    作用: 1,客户端连接服务端,并对服务端操作: (此功能已逐渐废弃,代替他的远程桌面): 2,telnet ip地址 端口号   用来测试Ip地址下,端口号是否可以被访问