UVA 10129

来源:互联网 发布:星星知我心第二部全集 编辑:程序博客网 时间:2024/06/06 20:42

题目大意:给你若干个单词,问你是否能够将其连成一队,使得对于除最后一个外的单词每个都成立如下关系:前一个单词的最后一个字母与后一个单词的第一个字母一致。也就是单词接龙。每个单词可能出现多次。

解题思路:将每个单词作为一个有向边,26个字母作为结点,也就是判断图是否有欧拉通路。有向图的欧拉通路要求在连通的情况下,出起点终点外每个结点的入度等于出度。起点的入度比出度小一,终点的入度比出度大一。样例比较水,所以有些不严苛的样例他都没考虑到。dfs判断连通,将有入度或出度的位置进入,如果能将所有字母都标记到为连通,再后面判断时用到。

ac代码:

#include <iostream>#include <cstring>#include <cmath>using namespace std;char st[1005];int n, m, t1, t2, sum, map[30][30];int jud, vis[30], ru[30], chu[30];void dfs(int n){vis[n] = 1;for (int i=0; i<26; i++)if (!vis[i] && map[n][i])dfs(i);}int main(){scanf("%d", &n); while (n--){scanf("%d", &m);jud = 1;memset(vis, 0, sizeof(vis));memset(map, 0, sizeof(map));memset(ru, 0, sizeof(ru));memset(chu, 0, sizeof(chu));for (int i=0; i<m; i++){scanf("%s", st);t1 = st[0]-'a';t2 = st[strlen(st)-1]-'a';map[t1][t2] = map[t2][t1] = 1;chu[t1]++, ru[t2]++;}for (int i=0; i<26; i++)if (ru[i] || chu[i]){dfs(i);break;}t1 = t2 = 0;for (int i=0; i<26; i++){if (ru[i]||chu[i]){if (!vis[i] || abs(ru[i]-chu[i])>=2){jud = 0;break;}if (ru[i]-chu[i] == 1)t1++;if (chu[i]-ru[i] == 1)t2++;}}if (jud && t1==t2){if (t1 == 1 || !t1)printf("Ordering is possible.\n");elseprintf("The door cannot be opened.\n");}elseprintf("The door cannot be opened.\n");}return 0;}
原创粉丝点击