UVA10129———欧拉道路
题目
输入n(n≤100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同(例如 acm,malform,mouse)。每个单词最多包含1000个小写字母。输入中可以有重复单词。
解题思路
把字母看作结点,单词看作有向边,则问题有解等价于图中存在欧拉道路。有向图中存在欧拉道路的条件有两个:一是底图(忽略边的方向后得到的无向图)连通,二是度数满足不存在奇点或奇点数为2。度数判读只要在输入时记录每个顶点的入度出度,而连通性判断有两种:DFS和并查集。
代码实现
dfs判断连通性+特判入出度
#include<stdio.h>
#include<cstring>
using namespace std; const int maxn = + ;
int G[maxn][maxn],in[maxn],out[maxn];
int vis[maxn]; //点是否访问,不是边
int n;
char word[ + ]; void dfs(int u)
{
vis[u] = ;
for (int v = ; v < maxn; v++) if (G[u][v])
{
G[u][v] = G[v][u] = ;
//G[u][v]--; G[v][u]--;
dfs(v);
}
} int main()
{
int T;
scanf("%d", &T);
while (T--)
{
memset(G, , sizeof(G));
memset(in, , sizeof(in));
memset(out, , sizeof(out));
memset(vis, , sizeof(vis));
scanf("%d", &n);
int start; //起点
while (n--)
{
scanf("%s", word);
int len = strlen(word);
int u = word[] - 'a', v = word[len - ] - 'a';
start = u;
vis[u] = vis[v] = -; //出现过的标为-1
G[u][v] = G[v][u] = ; //连通性按无向图处理
//G[u][v]++; G[v][u]++;
out[u]++; //度数按有向图处理
in[v]++;
} bool flag = true; //满足要求为true
int s_odd = ,t_odd = ; //起始奇点、结束奇点
for (int i = ; i < maxn; i++)
{
if (in[i] == out[i]) continue;
if (out[i] == in[i] + && !s_odd) { start = i; s_odd = ; }
else if (in[i] == out[i] + && !t_odd) t_odd = ;
else { flag = false; break; }
}
if (flag)
{
dfs(start); //也可以不从奇点出发,这个只是判断连通性
for (int i = ; i < maxn; i++)
if (vis[i] == -) { flag = false; break; }
} if (flag) printf("Ordering is possible.\n");
else printf("The door cannot be opened.\n");
}
return ;
}
并查集判断连通性+特判入出度
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std; const int maxn = + ;
int in[maxn], out[maxn], flag[maxn], p[maxn], fa[maxn];
int n; void init()
{
for (int i = ; i < ; i++)
fa[i] = i;
memset(in, , sizeof(in));
memset(out, , sizeof(out));
memset(flag, , sizeof(flag));
memset(p, , sizeof(p));
}
int find(int x)
{
if (fa[x] != x) return fa[x] = find(fa[x]);
return fa[x];
} void unite(int x, int y)
{
int rx = find(x);
int ry = find(y);
fa[rx] = ry;
} int main()
{
int T;
int a, b;
string str;
scanf("%d", &T);
while (T--)
{
init();
scanf("%d", &n);
for (int i = ; i < n; i++)
{
cin >> str;
a = str[] - 'a';
b = str[str.size() - ] - 'a';
unite(a, b);
in[a]++;
out[b]++;
flag[a] = flag[b] = ;
} int cnt = ; //记录连通分量
int root;
for (int i = ; i < ; i++)
{
if (flag[i])
{
root = find(i);
break;
}
}
for (int i = ; i < ; i++)
{
if (flag[i])
if (root != find(i)) cnt = ;
} if (cnt) {
printf("The door cannot be opened.\n");
continue;
} int k = ; //p[i]记录度数不等的
for (int i = ; i < ; i++)
{
if (flag[i] && in[i] != out[i]) p[k++] = i;
}
if (k == )
{
printf("Ordering is possible.\n");
continue;
}
if (k == && (in[p[]] - out[p[]] == && in[p[]] - out[p[]] == -) || (in[p[]] - out[p[]] == - && in[p[]] - out[p[]] == ))
{
printf("Ordering is possible.\n");
continue;
}
else
{
printf("The door cannot be opened.\n");
}
}
return ;
}
参考链接:https://blog.csdn.net/qq_29169749/article/details/51111377
UVA10129———欧拉道路的更多相关文章
- UVA-10129 Play on Words (判断欧拉道路的存在性)
题目大意:给出一系列单词,当某个单词的首字母和前一个单词的尾字母相同,则这两个单词能链接起来.给出一系列单词,问是否能够连起来. 题目分析:以单词的首尾字母为点,单词为边建立有向图,便是判断图中是否存 ...
- Uva 10129 - Play on Words 单词接龙 欧拉道路应用
跟Uva 10054很像,不过这题的单词是不能反向的,所以是有向图,判断欧拉道路. 关于欧拉道路(from Titanium大神): 判断有向图是否有欧拉路 1.判断有向图的基图(即有向图转化为无向图 ...
- UVa 10129 Play On Words【欧拉道路 并查集 】
题意:给出n个单词,问这n个单词能否首尾接龙,即能否构成欧拉道路 按照紫书上的思路:用并查集来做,取每一个单词的第一个字母,和最后一个字母进行并查集的操作 但这道题目是欧拉道路(下面摘自http:// ...
- Nyoj42 一笔画问题 (欧拉道路)
http://acm.nyist.net/JudgeOnline/problem.php?pid=42题目链接 #include <cstdio> #include <cstring ...
- 6-14 Inspector s Dilemma uva12118(欧拉道路)
题意:给出一个国家城市个数n 所需走过道路个数e 每条道路长t 该国家任意两个城市之间都存在唯一道路长t 要求 :找一条最短的路遍历所有所需走过的路 一开始以为是图的匹配 但是好 ...
- POJ 2513 Colored Sticks(欧拉道路+字典树+并查集)
http://poj.org/problem?id=2513 题意: 给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的. 思路: 题目很明 ...
- UVA 10129 Play on Words(欧拉道路)
题意:给你n个字符串,问你是否可以出现一条链,保证链中每个字符串的第一个元素与上一个字符串的最后一个元素相同,注意可能重复出现同一个字符串 题解:以每一个字符串第一个元素指向最后一个元素形成一个有向图 ...
- 【UVa】12118 Inspector's Dilemma(欧拉道路)
题目 题目 分析 很巧秒的一道题目,对着绿书瞎yy一会. 联一下必须要走的几条边,然后会形成几个联通分量,统计里面度数为奇数的点,最后再减去2再除以2.这样不断相加的和加上e再乘以t就是答案, ...
- UVA 10441 - Catenyms(欧拉道路)
UVA 10441 - Catenyms 题目链接 题意:给定一些单词,求拼接起来,字典序最小的,注意这里的字典序为一个个单词比过去,并非一个个字母 思路:欧拉回路.利用并查集判联通,然后欧拉道路判定 ...
随机推荐
- 微信小程序开发之https从无到有
本篇不讲什么是https,什么是SSL,什么是nginx 想了解这些的请绕道,相信有很多优秀的文章会告诉你. 本篇要讲的在最短的时间内,让你的网站从http升级到https. 开始教程前再说一句:ht ...
- apache日志信息详解
一.访问日志的格式 Apache内建了记录服务器活动的功能,这就是它的日志功能.下文详细介绍Apache的访问日志.错误日志.以及如何分析日志数据,如何定制Apache日志,如何从日志数据生成统计报 ...
- liist不同遍历优缺点
JAVA中循环删除list中元素的方法总结 印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个 ...
- Golang 读写锁RWMutex 互斥锁Mutex 源码详解
前言 Golang中有两种类型的锁,Mutex (互斥锁)和RWMutex(读写锁)对于这两种锁的使用这里就不多说了,本文主要侧重于从源码的角度分析这两种锁的具体实现. 引子问题 我一般喜欢带着问题去 ...
- PTA 水...
习题4-2 求幂级数展开的部分和 (20分) 已知函数e^x可以展开为幂级数1+x+x2/2!+x3/3!+⋯+xk/k!+⋯1+x+x^2 /2! + x^3 /3! + \cdots + x^k ...
- HDU 2063 过山车+poj 1469
//这是一个非常简单的匹配.其实满感觉这种算法讲道理是可以想到. //但是我们这种弱就只能先学了匈牙利算法,然后随便嗨这种题目了.没事结果都一样. //这就是匹配算法的DFS形式,有一个BFS形式的, ...
- 树莓派 zero w 一根线使用
参考网站:https://sspai.com/post/40086 硬件: 一台mac电脑 一根micro b usb线 一块zero w板子 一张micro sd卡 一.制卡 格式化 烧写镜像文件 ...
- P1223 [小数据版]边权差值最小的生成树
这道题和最小生成树kruskal的代码几乎相同,只不过不一定是最小生成树,所以不一定从最短的边开始做生成树:所以将每一条边分别作为起点,然后枚举就行了...... #include <bits/ ...
- Luogu P1754球迷购票问题【dp/卡特兰数】By cellur925
题目传送门 虽然是水dp,但我感到还是有些无从下手== f[i][j]表示还剩i个50元没考虑,j个100元没考虑的方案数,可有转移f[i][j]=f[i-1][j]+f[i][j-1] 但其实它也可 ...
- python实现希尔排序
与插入排序的思想一致,插入排序是一个,希尔排序是多个插入排序! # @File: shell_sort import random def insert_sort_gap(li, d): for i ...