codeforces 508D Tanya and Password (有向图欧拉通路)
来源:互联网 发布:钢结构工程量计算软件 编辑:程序博客网 时间:2024/05/11 02:36
While dad was at work, a little girl Tanya decided to play with dad's password to his secret database. Dad's password is a string consisting ofn + 2 characters. She has written all the possiblen three-letter continuous substrings of the password on pieces of paper, one for each piece of paper, and threw the password out. Each three-letter substring was written the number of times it occurred in the password. Thus, Tanya ended up withn pieces of paper.
Then Tanya realized that dad will be upset to learn about her game and decided to restore the password or at least any string corresponding to the final set of three-letter strings. You have to help her in this difficult task. We know that dad's password consisted of lowercase and uppercase letters of the Latin alphabet and digits. Uppercase and lowercase letters of the Latin alphabet are considered distinct.
The first line contains integer n (1 ≤ n ≤ 2·105), the number of three-letter substrings Tanya got.
Next n lines contain three letters each, forming the substring of dad's password. Each character in the input is a lowercase or uppercase Latin letter or a digit.
If Tanya made a mistake somewhere during the game and the strings that correspond to the given set of substrings don't exist, print "NO".
If it is possible to restore the string that corresponds to given set of substrings, print "YES", and then print any suitable password option.
5acaabaabacabbac
YESabacaba
4abcbCbcb1b13
NO
7aaaaaaaaaaaaaaaaaaaaa
YESaaaaaaaaa
题目大意:给一个n,输入n个长度为3的字符串,字符包含英文的大小写和数字,判断是否存在一个长度为n+2的字符串包含全部n个子串
题目分析:可以把问题转化为判断是否存在欧拉通路,那如何构图?因为题目说了每个字符串的长度为3,因此我们把它的前两个字符当做一个结点,后两个字符当作一个结点,然后构建一个有向图,只需要判断这张图是否存在欧拉通路即可,欧拉通路是一条经过图(无向图或有向图)中所有边一次且仅一次行遍图中所有顶点的通路。这题和poj2377有点类似,但是这题有两点比那题棘手,1是结点的存储问题,那题是尾首字符相同便可链接,而这题需要将结点散列,因为一共就10+26+26=62个字符,我们先将62个字符从1到61编号再把结点设置为62x+y的整型变量,则可以将所有结点表示出来。还有个麻烦的地方在于数据量,本题的n即边数达到20w,如果已经判断存在欧拉通路,按照点dfs来找的话,平行边和自环一多很有可能超时甚至爆栈,因此我们可以用边来找,用边找的好处是找的过程中可以把自环和平行的都去掉,下面就是如何判断是否存在欧拉通路的问题,这里简单说,(我有详细介绍此类问题的博文)
1.并查集判连通
2.出入度都相等则为欧拉回路,dfs起点任意,若出入度相差1的点的个数不大于2则把出度大的做为起点,若个数大于2或者出入度相差超多1则不存在欧拉通路
#include <cstdio> #include <cstring> int const MAX = 200005; int const MAX2 = 4000; bool has[MAX2]; int fa[MAX2], out[MAX2], in[MAX2], path[MAX], e[MAX2][MAX2]; int n, len, st; struct node { int u, v; char name[3]; }r[MAX]; int abs(int x) { return x > 0 ? x : -x; } void UF_set() { for(int i = 0; i < MAX2; i++) fa[i] = i; } int Find(int x) { return x == fa[x] ? x : fa[x] = Find(fa[x]); } void Union(int a, int b) { int r1 = Find(a); int r2 = Find(b); if(r1 != r2) fa[r1] = r2; } int ctoi(char ch) { if(ch >= 'A' && ch <= 'Z') return ch - 'A' + 10; if(ch >= 'a' && ch <= 'z') return ch - 'a' + 36; return ch - '0'; } char itoc(int a) { if(a >= 0 && a <= 9) return '0' + a; if(a >= 10 && a <= 35) return 'A' + a - 10; return 'a' + a - 36; } bool Exist() { int t = -1; for(int i = 0; i < MAX2; i++) { if(has[i]) { if(t == -1) t = Find(i); else if(Find(i) != t) return false; } } int sum = 0, tmp; for(int i = 0; i < MAX2; i++) { if(has[i]) { tmp = i; if(in[i] != out[i]) { sum++; if(abs(in[i] - out[i]) > 1) return false; if(out[i] > in[i]) st = i; } } } if(sum > 2) return false; if(sum == 0) st = tmp; return true; } void DFS(int now) { for(int i = 0; i < MAX2; i++) { while(e[now][i]) { e[now][i]--; DFS(i); path[len++] = i; } } } int main() { scanf("%d", &n); UF_set(); memset(e, 0, sizeof(e)); for(int i = 0; i < n; i++) { scanf("%s", r[i].name); r[i].u = ctoi(r[i].name[0]) * 62 + ctoi(r[i].name[1]); r[i].v = ctoi(r[i].name[1]) * 62 + ctoi(r[i].name[2]); has[r[i].u] = true; has[r[i].v] = true; Union(r[i].u, r[i].v); out[r[i].u]++; in[r[i].v]++; e[r[i].u][r[i].v]++; } if(!Exist()) printf("NO\n"); else { len = 0; DFS(st); path[len++] = st; printf("YES\n"); printf("%c%c", itoc(path[len - 1] / 62), itoc(path[len - 1] % 62)); for(int i = len - 2; i >= 0; i--) printf("%c", itoc(path[i] % 62)); printf("\n"); } }
- codeforces 508D Tanya and Password (有向图欧拉通路)
- Codeforces 508D Tanya and Password 欧拉通路Euler
- codeforces - 508D - Tanya and Password(欧拉通路)
- codeforces Round#288D Tanya and Password 欧拉通路
- Codeforces 508D Tanya and Password
- Codeforces 508D Tanya and Password
- Codeforces Round #288 (Div. 2)D.Tanya and Password——欧拉通路
- Codeforces Round #288 (Div. 2) D. Tanya and Password (欧拉通路)
- codeforces 508 D. Tanya and Password (fleury算法)
- Codeforces 508D - Tanya and Password (欧拉道路)
- Tanya and Password - CodeForces 508 D 欧拉路径
- CodeForces 508D Tanya and Password(欧拉路径)
- CodeForces 508D Tanya and Password欧拉路径
- 有向图欧拉回路 Codeforces508D Tanya and Password
- CodeForces 508D(Codeforces Round #288 (Div. 2))Tanya and Password
- Codeforces Round #288 (Div. 2)---D. Tanya and Password
- Codeforces Round #288 (Div. 2) D. Tanya and Password
- 【欧拉回路】 Codeforces 288 D Tanya and Password
- 2014年的一点个人总结!
- nmake工具的用法
- 策划,程序,美术,运营,市场,你到底有多重要?
- Android Broadcast 和 BroadcastReceiver的权限限制
- JavaEE中的依赖性——依赖性注入
- codeforces 508D Tanya and Password (有向图欧拉通路)
- Mysql 索引的创建删除修改
- LeetCode-Balanced Binary Tree
- rt-thread通过TCP连接(网络+shell)方式调用list_if()导致网络断开的问题分析
- BOOST学习
- JavaEE中的依赖性——声明依赖性
- 奈氏准则和香浓公式
- poj 1961
- javascript推荐书籍