http://acm.nyist.net/JudgeOnline/problem.php?pid=99

TLE: 首先建立一个Trie树,然后利用dfs贪心地去寻找可以拼接的单词。在dfs中,由于每次都是从最小的字母开始找起,所以只要能够找到就一定保证是字典序最小的。。。可惜超时了。。其实仔细想想也是的,每一个节点都要循环26次。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;const int maxn = 1000;
struct Node
{int id,back;Node *next[26];
};
int n,cnt,ans[maxn];
char str[1010][30];
bool vis[maxn];
Node *T;void build(char *s)
{int len = strlen(s);Node *p = T;for(int i = 0; i < len; i++){if(p->next[s[i]-'a'] == NULL){p->next[s[i]-'a'] = (Node *)malloc(sizeof(Node));p->next[s[i]-'a']->id = p->next[s[i]-'a']->back = 0;for(int j = 0; j < 26; j++)p->next[s[i]-'a']->next[j] = NULL;}p = p->next[s[i]-'a'];}p->id = ++cnt; p->back = s[len-1] - 'a';
}bool dfs(Node *root,int num)
{if(root == NULL) return false;if(root->id > 0 && vis[root->id] == false){ans[num] = root->id;if(num == n) return true;vis[root->id] = true;if(dfs(T->next[root->back],num+1)) return true;vis[root->id] = false;return false;}for(int i = 0; i < 26; i++){if(root->next[i] == NULL) continue;if(dfs(root->next[i],num)) return true;}return false;
}int main()
{   int t;scanf("%d",&t);while(t--){T = (Node *)malloc(sizeof(Node));T->id = T->back = 0; for(int i = 0; i < 26; i++) T->next[i] = NULL;cnt = 0;scanf("%d",&n);for(int i = 1; i <= n; i++){getchar();scanf("%s",str[i]);build(str[i]);}memset(vis,false,sizeof(vis));if(dfs(T,1)){for(int i = 1; i <= n; i++)if(i == 1)printf("%s",str[ans[i]]);else printf(".%s",str[ans[i]]);}else printf("***");printf("\n");}return 0;
}

AC(copy别人的):以字母为节点的有向图的欧拉路径,有向图的欧拉路径的充要条件是所有节点的入度等于出度,或者有一个节点的入度比出度小1,同时有一个节点的入度比出度大1。当然首先这个图得是连通的,后面会通过DFS来判断。
首先通过入度出度的条件判断能否形成欧拉路径。
若能形成,则让入度比出度小1的节点作为起始点(若没有这样的节点,就按字典顺序选第1个出现的字母作为起始点),进行dfs,找到满足条件的路径,若dfs找不到,那说明该图还是连通图

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{char s[31];int first,last;
};node a[1001];
int degree_in[1001],degree_out[1001],m,order[1001];
bool used[1001];int f()
{int x1,x2,ans=0,i;x1=x2=0;for(i=0;i<26;++i){if(abs(degree_in[i]-degree_out[i])>=2)return -1;else if(degree_in[i]-degree_out[i]==1)x1++;else if(degree_in[i]-degree_out[i]==-1){x2++;ans=i;}}if(x1>1||x2>1) //当时三个度时,必定是 12 和21,相同的不能大于等于2,不然不能构成欧拉回路return -1;else if(x1==0){for(i=0;i<26;++i)if(degree_out[i])return i; //找到一个就行}elsereturn ans;}
bool cmp(node a,node b)
{return strcmp(a.s,b.s)<0;
}bool dfs(int st,int cnt)
{int i;if(cnt==m)return 1;for(i=0;i<m;++i){if(a[i].first<st||used[i])continue;else if(a[i].first>st)return false;used[i]=true;order[cnt]=i;if(dfs(a[i].last,cnt+1))return 1;used[i]=false;//回溯判断是否形成欧拉路径}return false;
}int main()
{int N,len,i,start;scanf("%d",&N);while(N--){memset(used,false,sizeof(used));memset(degree_out,0,sizeof(degree_out));memset(degree_in,0,sizeof(degree_in));scanf("%d",&m);for(i=0;i<m;++i){scanf("%s",a[i].s);len = strlen(a[i].s);a[i].first =a[i].s[0]-'a';a[i].last =a[i].s[len-1]-'a';degree_out[a[i].s[0]-'a']++;degree_in[a[i].s[len-1]-'a']++;//注意这里的入肚出度}start=f();if(start ==-1){printf("***\n");continue;}sort(a,a+m,cmp);if(!dfs(start,0)){printf("***\n");continue;}printf("%s",a[order[0]].s);for(i=1;i<m;i++)printf(".%s",a[order[i]].s);printf("\n");}return 0;
}

nyoj99(欧拉路)相关推荐

  1. 图论--欧拉路,欧拉回路(小结)

    在题目中在慢慢细说概念 1.HDU - 3018 Ant Trip 题目大意:又N个村庄,M条道路.问须要走几次才干将全部的路遍历 解题思路:这题问的是有关欧拉路的判定 欧拉路就是每条边仅仅能走一次, ...

  2. 小A与欧拉路(牛客-树的直径)

    题解: 欧拉路:从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边只通过恰好一次 问你走完这树上所有的点最短路径是什么. 因为树是没有环的,所以你走到叶子结点的时候需要往回走,也就是再走一 ...

  3. 图论-欧拉路(UVA10054)(HDU1116)

    首先说一下定义: 欧拉路:从图中某点出发可以遍历全图,图中的每条边通过且只能通过一次. 欧拉回路:具有欧拉路性质且起点位置与终点位置相同. 主要问题就是一个图中是否存在欧拉路,和打印欧拉路路径. 先说 ...

  4. 模板 - 欧拉路、欧拉回路(一笔画问题)

    整理的算法模板合集: ACM模板 目录 非递归版 普通递归版 HierholzersHierholzersHierholzers算法(输出字典序最小的答案) FleuryFleuryFleury算法 ...

  5. 欧拉回路与欧拉路(模板)

    欧拉回路 欧拉图: 就是从任意一个点开始都可以一笔画完整个图 半欧拉图: 必须从某个点开始才能一笔画完整个图. 对于无向图 , 是欧拉图当且仅当 是连通的且没有奇度顶点. 对于无向图 , 是半欧拉图当 ...

  6. [欧拉路]CF1152E Neko and Flashback

    1152E - Neko and Flashback 题意:对于长为n的序列c和长为n - 1的排列p,我们可以按照如下方法得到长为n - 1的序列a,b,a',b'. ai = min(ci, ci ...

  7. hihoCoder #1182 欧拉路·三 (变形)

    题意: 写出一个环,环上有2^n个格子,每个格子中的数字是0或1,相连着的n个格子可以组成一个数的二进制,要求给出这2^n个数字的序列,使得组成的2^n个数字全是不同的.(即从0到2^n-1) 思路: ...

  8. hihocder 1181 : 欧拉路·二

    因为相连的两个数字总是相同的,不妨我们只写一次,那么这个例子可以写成:3-2-4-3-5-1.6个数字刚好有5个间隙,每个间隙两边的数字由恰好对应了一块骨牌. 如果我们将每一个数字看作一个点,每一块骨 ...

  9. #1182 : 欧拉路·三(有向图的欧拉路)

    #1182 : 欧拉路·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho破解了一道又一道难题,终于来到了最后一关.只要打开眼前的宝箱就可以通关这个游戏了 ...

  10. #1181 : 欧拉路·二(无向图的欧拉路)

    #1181 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌. ...

最新文章

  1. 干货丨一文看懂什么是知识图谱!
  2. Go语言 goroutine
  3. Linux du指令
  4. linux常用的脚本、命令
  5. c#中tcp协议服务器同时接收客户端的数据
  6. Unity游戏框架设计
  7. VS log4net引用错误的解决
  8. markdown 文档转 word
  9. 简述导线平差计算的五个步骤_结点导线如何平差
  10. Mybatis面向接口编程
  11. focus和onfocus区别
  12. Pandas如何读取保存Excel
  13. 为了下半年的「双 11」,阿里的「赚钱机器」开始冲刺
  14. 一个神奇的测试_神奇的心理测试:一个问题就能测试出你的情商!超准慎测
  15. CHAPTER 23 Question Answering
  16. @Aspect注解用法
  17. echarts折线图动态多条线
  18. Vuforia直播笔记
  19. Wow.js常用特效对应名称
  20. 天天用身份证,你知道这背后的秘密么?

热门文章

  1. 推你所想,神策智能推荐 Demo 上线(可免费体验)
  2. 几分钟了解阿里云云服务器ECS
  3. 在VIM里面设置自动补全功能
  4. 项目开发--------XMPP即时通讯
  5. Perl中use、require的用法和区别
  6. 将frm,myi,myd文件打包成sql文件
  7. tomcat向weblogic移植需要注意的问题
  8. application time for the banking industry
  9. if you canget up early
  10. 什么时候必须使用UI相机? 多个相机的作用原理?