判断欧拉路径是否存在及求出字典序最小的欧拉路径问题(如果存在)。

将字符串的第一个字母和最后一个字母间连边,将字母看成点,最多可能有26个点(a-z),如果有欧拉路径,还要判断是否有欧拉回路,如果有,则需要找一个字典序最小的点开始生成这条链,否则以起点开始生成链,起点即为出度比入度大1的点。

欧拉路径是否存在的判定:

1.全部点在一个联通块                               ----用并查集判联通块的数量
2.所有点出度入度相等                               ----in[],out[]记录出度与入度
3.或者有一个出度比入度小1,另一个出度比入度大1(源点与汇点)

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#define Mod 1000000007
using namespace std;
#define N 2007 string ss[N]; struct node
{
int u,v,next;
string w;
}G[N]; int first[],fa[],in[],out[],vis[];
int tot,k,start;
int evis[N];
string ans[N]; void init()
{
int i;
for(i=;i<;i++)
fa[i] = i;
tot = ;
memset(in,,sizeof(in));
memset(out,,sizeof(out));
for(i=;i<=;i++)
{
G[i].u = G[i].v = G[i].next = ;
G[i].w = "";
}
memset(first,-,sizeof(first));
memset(vis,,sizeof(vis));
memset(evis,,sizeof(evis));
for(int j=;j<=;j++)
ans[j] = "";
} int findset(int x)
{
if(x != fa[x])
fa[x] = findset(fa[x]);
return fa[x];
} int cmp(string ka,string kb)
{
return ka>kb;
} void addedge(int u,int v,string w)
{
G[tot].u = u;
G[tot].v = v;
G[tot].w = w;
G[tot].next = first[u];
first[u] = tot++;
out[u]++;
in[v]++;
vis[u] = vis[v] = ;
int fx = findset(u);
int fy = findset(v);
if(fx != fy)
fa[fx] = fy;
} int Euler_Path()
{
int block = ,i;
int O = ;
int I = ;
start = -;
for(i=;i<;i++)
{
if(vis[i]) //涉及到的字母
{
int fk = findset(i);
if(fk == i)
block++;
if(block > )
return false;
if(in[i] == out[i]+) //入大出,奇度数点
I++;
else if(in[i]+ == out[i]) //出大入,奇度数点
O++,start = i;
else if(in[i] != out[i])
return false;
}
}
if(block != )
return false;
if((O == I && O == ) || (O == I && O == )) //没有奇度数点或者只有源点和汇点是奇度数点
{
if(start == -) //没有找到起点,是欧拉回路
{
for(i=;i<;i++)
{
if(vis[i] && out[i] > ) //找字典序最小的字母做起点
{
start = i;
return true;
}
}
}
//如果已找到起点,则不能是欧拉回路
if(O == I && O == )
return true;
return false;
}
return false;
} void dfs(int v,int flag)
{
for(int e=first[v];e!=-;e=G[e].next)
{
if(!evis[e]) //边没被访问
{
evis[e] = ;
dfs(G[e].v,e);
}
}
if(flag != -)
ans[k++] = G[flag].w;
} int main()
{
int t,i,j,n;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d",&n);
for(i=;i<=n;i++)
cin>>ss[i];
sort(ss+,ss+n+,cmp);
//qsort(ss+1,n,28,cmp);
for(i=;i<=n;i++)
{
int u = ss[i][]-'a';
int v = ss[i][ss[i].length()-]-'a';
addedge(u,v,ss[i]);
}
if(Euler_Path())
{
k = ;
dfs(start,-);
cout<<ans[k-];
for(i=k-;i>=;i--)
cout<<"."<<ans[i];
printf("\n");
}
else
puts("***");
}
return ;
}

UESTC 917 方老师的分身IV --求欧拉路径的更多相关文章

  1. UESTC 901 方老师抢银行 --Tarjan求强连通分量

    思路:如果出现了一个强连通分量,那么走到这个点时一定会在强连通分量里的点全部走一遍,这样才能更大.所以我们首先用Tarjan跑一遍求出所有强连通分量,然后将强连通分量缩成点(用到栈)然后就变成了一个D ...

  2. UESTC 914 方老师的分身I Dijkstra

    题意:求有向图的往返最短路的最长长度. 分析:求第一次到所有点的距离可以用一次Dijkstra求最短路求出来.考虑回来的路,想想就知道,从每个点回来的路即为将边的方向反转再求一次最短路后的结果. 所以 ...

  3. UESTC 915 方老师的分身II --最短路变形

    即求从起点到终点至少走K条路的最短路径. 用两个变量来维护一个点的dis,u和e,u为当前点的编号,e为已经走过多少条边,w[u][e]表示到当前点,走过e条边的最短路径长度,因为是至少K条边,所以大 ...

  4. UESTC 916 方老师的分身III --拓扑排序

    做法: 如果有a<b的关系,则连一条a->b的有向边,连好所有边后,找入度为0的点作为起点,将其赋为最小的价值888,然后其所有能到的端点,价值加1,加入队列,删去上一个点,然后循环往复, ...

  5. UESTC_方老师的分身 II CDOJ 915

    方老师的分身 II Time Limit: 10000/5000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  6. UESTC 898 方老师和缘分 --二分图匹配+强连通分量

    这题原来以为是某种匹配问题,后来好像说是强连通的问题. 做法:建图,每个方老师和它想要的缘分之间连一条有向边,然后,在给出的初始匹配中反向建边,即如果第i个方老师现在找到的是缘分u,则建边u-> ...

  7. UESTC - 900 方老师炸弹 —— 割点

    题目链接:https://vjudge.net/problem/UESTC-900   方老师炸弹 Time Limit: 4000/2000MS (Java/Others)     Memory L ...

  8. UESTC 900 方老师炸弹 --Tarjan求割点及删点后连通分量数

    Tarjan算法. 1.若u为根,且度大于1,则为割点 2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边) 3.若low[v]>dfn[u], ...

  9. UESTC 884 方老师的专题讲座 --数位DP

    定义:cnt[L][K]表示长度为L,最高位为K的满足条件C的个数. 首先预处理出cnt数组,枚举当前长度最高位和小一个长度的最高位,如果相差大于2则前一个加上后一个的方法数. 然后给定n,计算[1, ...

随机推荐

  1. ahjesus fstab修改错误了如何修复

    fstab修改错误了如何修复   当你不小心把磁盘表输入错误以后,系统总是让你按ctrl+D重新启动或者输入密 码进入shell,你输入密码登陆后,   编辑文件是只读的,执行下面的命令后就可以编辑了 ...

  2. [翻译]:SQL死锁-阻塞探测

    到了这篇,才是真正动手解决问题的时候,有了死锁之后就要分析死锁的原因,具体就是需要定位到具体的SQL语句上.那么如何发现产生死锁的问题本质呢?下面这篇讲的非常细了,还提到了不少实用的SQL,但对我个人 ...

  3. dapper的增、删、查改的CodeSmith模板

    <%@ Template Language="C#" TargetLanguage="Text" %> <%@ Property Name=& ...

  4. Gulp-前端进阶A-2

    1.js压缩 注意在根目录的package.json文件里在成功安装uglify后要有 "gulp-uglify": "^1.5.4" 才行 var gulp ...

  5. gulp入坑系列(4)——gulp的代码转换

    当然,gulp不仅仅能转换Sass,这里会提到如下转换: jsx转换成常规的JavaScript(说到jsx,玩过react的同学应该是知道的) es6转换为es5 Less,Sass转换为CSS 首 ...

  6. log4net 日志框架的配置

    log4net 日志框架的配置——静态文件(一) 添加对log4net程序集的引用 选择程序集文件添加引用即可,需要注意的是需要添加相应程序版本的程序集,如果你的应用是基于.netFramework2 ...

  7. SAP中关于用户IP信息的获取(转载)

    SAP中如何获取登录用户的IP? 或如何查看哪些IP登录到SAP中: 在Table: USR41中查看,具体字段的说明如下: MANDT   ---   ClientBNAME   ---   登录的 ...

  8. android Java BASE64编码和解码二:图片的编码和解码

    1.准备工作 (1)在项目中集成 Base64 代码,集成方法见第一篇博文:android Java BASE64编码和解码一:基础 (2)添加 ImgHelper 工具类 package com.a ...

  9. HBase数据模型剖析

    出处:http://wuyudong.com/1987.html HBase 进行数据建模的方式和你熟悉的关系型数据库有些不同.关系型数据库围绕表.列和数据类型——数据的形态使用严格的规则.遵守这些严 ...

  10. MAC中安卓开发环境的下载(转)

    今天终于为我的Macbook Pro Retina搭建好了Android开发环境,几经折磨,差点放弃了: 总结如下:1.最好选择ADT Bundle,这里面已经集成好了Eclipse.ADT.Andr ...