题意:给n个字符串(3<=n<=1000),当字符串str[i]的尾字符与str[j]的首字符一样时,可用dot连接。判断用所有字符串一次且仅一次,连接成一串。若可以,输出答案的最小字典序(dot是最小字典序的,比‘a'小)。

显然就是以26个字母为结点,n个字符串为边,求解有向图的欧拉通路。

不过这里要注意,26个字母不一定都用上。

先判断有向图的欧拉通路的条件是否成立:

1.有一个结点入度等于出度+1且有一个结点出度等于入度+1且其他结点入度等于出度。(或所有结点入度等于出度)

2.有向图的基图连通。(把有向边改成无向边后,图连通)

感觉中间那段while(top)可以当做模板来用了,具体机理这里不详细说了,看着想一想还是能理解的。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <set>
#include <queue>
#include <map>
#include <stack>
using namespace std; #define MP make_pair
#define ll long long
#define inf 0x3f3f3f3f int in[30],out[30];
struct Edge{
int v,nxt;
bool vis;
}e[1010];
int head[30],esz;
void addedge(int u,int v){
e[esz].v=v,e[esz].nxt=head[u];
e[esz].vis=false;
head[u]=esz++;
}
int fa[30];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
bool jud(){
for(int i=0;i<26;++i) fa[i]=i;
int st;
for(int u=0;u<26;++u){
for(int j=head[u];j!=-1;j=e[j].nxt){
int v = e[j].v;
st = fa[find(u)] = find(v);
}
}
for(int i=0;i<26;++i){
if(out[i]+in[i] && find(i)!=find(st)) return false;
}
return true;
}
int main(){
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
string s[1010];
for(int i=0;i<n;++i){
char tmp[22];
scanf("%s",tmp);
s[i] = tmp;
}
sort(s,s+n);
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
queue<string>val[30][30];
esz=0; memset(head,-1,sizeof(head));
for(int i=n-1;i>=0;--i){
int u = s[i][0]-'a', v = s[i][s[i].size()-1]-'a';
out[u]++; in[v]++;
addedge(u,v);
}
for(int i=0;i<n;++i){
int u = s[i][0]-'a', v = s[i][s[i].size()-1]-'a';
val[u][v].push(s[i]);
}
int j1=-1,j2=-1,j3=1;
for(int i=0;i<26;++i){
if(in[i]==out[i]) continue;
if(out[i]==in[i]+1){
if(j1==-1) j1=i;
else j3=0;
continue;
}
if(in[i]==out[i]+1){
if(j2==-1) j2=i;
else j3=0;
continue;
}
j3=0;
}
if((j1^j2)<0) j3=0;
if(j3==0 || jud()==false){
puts("***");
continue;
}
if(j1==-1){
for(int i=0;i<26;++i){
if(out[i]){
j1=i;
break;
}
}
}
stack<int>st;
vector<int>ans;
st.push(j1);
while(!st.empty()){
int u = st.top(); st.pop();
bool f = false;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v = e[i].v;
if(e[i].vis) continue;
e[i].vis = true;
st.push(u);
st.push(v);
f=true;
break;
}
if(f==false) ans.push_back(u);
}
for(int i=ans.size()-1;i;--i){
int u = ans[i];
int v = ans[i-1];
printf("%s",val[u][v].front().c_str());
val[u][v].pop();
if(i!=1) printf(".");
else puts("");
}
}
return 0;
}

POJ 2337 Catenyms(有向图的欧拉通路)的更多相关文章

  1. hdu1116有向图判断欧拉通路判断

    Play on Words Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  2. Colored Sticks POJ - 2513 并查集+欧拉通路+字典树hash

    题意:给出很多很多很多很多个棒子 左右各有颜色(给出的是单词) 相同颜色的可以接在一起,问是否存在一种 方法可以使得所以棒子连在一起 思路:就是一个判欧拉通路的题目,欧拉通路存在:没奇度顶点   或者 ...

  3. POJ - 2513 Colored Sticks(欧拉通路+并查集+字典树)

    https://vjudge.net/problem/POJ-2513 题解转载自:優YoU  http://user.qzone.qq.com/289065406/blog/1304742541 题 ...

  4. POJ 1386 Play on Words(有向欧拉通路 连通图)

    题意  见下方中文翻译 每一个单词能够看成首尾两个字母相连的一条边  然后就是输入m条边  推断是否能构成有向欧拉通路了 有向图存在欧拉通路的充要条件: 1. 有向图的基图连通: 2. 全部点的出度和 ...

  5. Poj 2337 Catenyms(有向图DFS求欧拉通路)

    题意: 给定n个单词, 问是否存在一条欧拉通路(如acm,matal,lack), 如果存在, 输出字典序最小的一条. 分析: 这题可以看作http://www.cnblogs.com/Jadon97 ...

  6. POJ 1300 欧拉通路&欧拉回路

    系统的学习一遍图论!从这篇博客开始! 先介绍一些概念. 无向图: G为连通的无向图,称经过G的每条边一次并且仅一次的路径为欧拉通路. 如果欧拉通路是回路(起点和终点相同),则称此回路为欧拉回路. 具有 ...

  7. poj 2513 连接火柴 字典树+欧拉通路 好题

    Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 27134   Accepted: 7186 ...

  8. POJ 2513 无向欧拉通路+字典树+并查集

    题目大意: 有一堆头尾均有颜色的木条,要让它们拼接在一起,拼接处颜色要保证相同,问是否能够实现 这道题我一开始利用map<string,int>来对颜色进行赋值,好进行后面的并查操作以及欧 ...

  9. poj2513- Colored Sticks 字典树+欧拉通路判断

    题目链接:http://poj.org/problem?id=2513 思路很容易想到就是判断欧拉通路 预处理时用字典树将每个单词和数字对应即可 刚开始在并查集处理的时候出错了 代码: #includ ...

随机推荐

  1. JQUERY获取当前页面的URL信息

    以前在做网站的时候,经常会遇到当前页的分类高亮显示,以便让用户了解当前处于哪个页面.之前一直是在每个不 同页面写方法.工程量大,也不便于修改.一直在想有什么简便的方法实现.后来在网上查到可以用获取当前 ...

  2. caffe的python接口学习(6):用训练好的模型(caffemodel)来分类新的图片

    经过前面两篇博文的学习,我们已经训练好了一个caffemodel模型,并生成了一个deploy.prototxt文件,现在我们就利用这两个文件来对一个新的图片进行分类预测. 我们从mnist数据集的t ...

  3. C#进阶系列——DDD领域驱动设计初探(四):WCF搭建

    前言:前面三篇分享了下DDD里面的两个主要特性:聚合和仓储.领域层的搭建基本完成,当然还涉及到领域事件和领域服务的部分,后面再项目搭建的过程中慢慢引入,博主的思路是先将整个架构走通,然后一步一步来添加 ...

  4. App 引导界面

    App 引导界面 1.前言 最近在学习实现App的引导界面,本篇文章对设计流程及需要注意的地方做一个浅显的总结. 附上项目链接,供和我水平类似的初学者参考——http://files.cnblogs. ...

  5. 响应式疑惑? CSS单位研究

    各种单位要搞清楚,自己试一试,实践出真知! 2.屏幕分辨率    响应式 哦,电脑的分辨率:1440x900表示水平有1440个像素点哦! 垂直有900个像素点. 而网页在浏览器中,所以宽度是电脑的分 ...

  6. Scrapy的中Css 选择器

    //通过 名为 video_part_lists 的Class 中下面的 li 标签 liList = response.css('.video_part_lists li') for li in l ...

  7. 一些js 插件的作用

    前言: 从一些开源网站上下载下来的 后台管理系统模板一般会有很多的js ,其js 的功能是什么呢?这里随手查询了一下,记录下来 正文: 1.zDialog.js 各种弹窗插件详细案例:http://w ...

  8. C# 在类中反射

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Wind ...

  9. chkdsk磁盘修复命令工具怎么用,怎样运行chkdsk工具修复?

    Chkdsk是系统检查磁盘当前状态的一个命令,启动它可以显示磁盘状态.内存状态和指定路径下指定文件的不连续数目.选择“开始→运行”输入“Chkdsk”回车,即可启动Chkdsk,它会自动校验文件并将丢 ...

  10. 11月8日下午Jquery取属性值(复选框、下拉列表、单选按钮)、做全选按钮、JSON存储、去空格

    1.jquery取复选框的值 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "htt ...