每个单词可以看做一条边,每个字母就是顶点。

有向图欧拉回路的判定,首先判断入度和出度,其实这个题判定的是欧拉通路,不一定非得构成环,所以可以有一个点的顶点入度比出度大1,另外一个点的出度比入度大1,或者每个点的出度和入度相等。用并查集判断是否弱联通。最后dfs求出欧拉路径,不过这个题是让求字典序最小的那个,所以加边之前先把边排序。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
const int maxn = ;
struct Edge {
int to, next;
int id;
}edge[maxn * ];
int tot, head[maxn];
int in[maxn], out[maxn];
int F[maxn];
int st;
bool vis[];
string str[maxn];
void init()
{
tot = ;
memset(head, -, sizeof(head));
memset(F, -, sizeof(F));
}
void addedge(int u, int v, int id)
{
edge[tot].to = v;
edge[tot].next = head[u];
edge[tot].id = id;
head[u] = tot++;
}
int Find(int x)
{
if (F[x] == -) return x;
return F[x] = Find(F[x]);
}
void Union(int x, int y)
{
int tx = Find(x);
int ty = Find(y);
if (tx != ty)
F[tx] = ty;
}
bool check(int s)
{
int in1 = , out1 = ;
for (int i = ; i <= ; i++)//判断出入度关系
{
if (in[i] == out[i]) continue;
else if (in[i] - out[i] == ) in1++;
else if (out[i] - in[i] == ) out1++, st = i;//如果有出度比入度大1的,说明是欧拉通路,起点只能是那个出度比入度大1的那个点
else return false;
}
//printf("in1 = %d, out1 = %d\n", in1, out1);
if (!(in1 == && out1 == ) && !(in1 == && out1 == )) return false;
for (int i = ; i <= ; i++)//判断弱联通
if (vis[i] && Find(i) != Find(s))
return false;
return true;
}
bool vis2[maxn * ];//判断每条边是否访问过。
int top;
int ans[maxn * ];//保存路径
void dfs(int u)
{
for (int i = head[u]; i != -; i = edge[i].next)
{
if (!vis2[i])
{
vis2[i] = true;
dfs(edge[i].to);
ans[top++] = i;
}
}
}
int main()
{
int T, n;
scanf("%d", &T);
while (T--)
{
init();
scanf("%d", &n);
memset(in, , sizeof(in));
memset(out, , sizeof(out));
memset(vis, false, sizeof(vis));
int u, v;
st = ;
for (int i = ; i <n; i++)
cin >> str[i];
sort(str, str + n);//从小到大排序
for (int i = n - ; i >= ; i--)//因为链式前向星是逆序存图,所以反过来从大到小读入。
{
u = str[i][] - 'a' + ;
v = str[i][str[i].length() - ] - 'a' + ;
vis[u] = vis[v] = true;
addedge(u, v, i);
++in[v];
++out[u];
Union(u, v);
st = min(st, min(u, v));//找出最小的那个点来
}
if (!check(st))
puts("***");
else
{
top = ;
memset(vis2, false, sizeof(vis2));
dfs(st);
for (int i = top - ; i > ; i--)
cout << str[edge[ans[i]].id] << ".";
cout << str[edge[ans[]].id] << endl;
} }
return ;
}

有向图的欧拉路径POJ2337的更多相关文章

  1. poj 2337 有向图输出欧拉路径

    Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10186   Accepted: 2650 Descrip ...

  2. poj2337 欧拉路径

    poj2337 这道题昨天晚上开始做,今天才A.但是问题想透了, 发现其实没那么难 题目大意: 给你一些单词,如果一个单词的末尾字符与另一个单词首字符相同,则两个的单词可以连接.问是否可以把所有单词连 ...

  3. HDU 1116 Play on Words(欧拉路径(回路))

    http://acm.hdu.edu.cn/showproblem.php?pid=1116 题意:判断n个单词是否可以相连成一条链或一个环,两个单词可以相连的条件是 前一个单词的最后一个字母和后一个 ...

  4. Play on Words UVA - 10129 欧拉路径

    关于欧拉回路和欧拉路径 定义:欧拉回路:每条边恰好只走一次,并能回到出发点的路径欧拉路径:经过每一条边一次,但是不要求回到起始点 ①首先看欧拉回路存在性的判定: 一.无向图每个顶点的度数都是偶数,则存 ...

  5. POJ 1637 混合图的欧拉回路判定

    题意:一张混合图,判断是否存在欧拉回路. 分析参考: 混合图(既有有向边又有无向边的图)中欧拉环.欧拉路径的判定需要借助网络流! (1)欧拉环的判定:一开始当然是判断原图的基图是否连通,若不连通则一定 ...

  6. POJ 1637 Sightseeing tour (混合图欧拉路判定)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6986   Accepted: 2901 ...

  7. SPOJ Play on Words

    传送门 WORDS1 - Play on Words #graph-theory #euler-circuit Some of the secret doors contain a very inte ...

  8. Sightseeing tour

    Sightseeing tour Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8276 Accepted: 3489 Desc ...

  9. POJ 1637 - Sightseeing tour - [最大流解决混合图欧拉回路]

    嗯,这是我上一篇文章说的那本宝典的第二题,我只想说,真TM是本宝典……做的我又痛苦又激动……(我感觉ACM的日常尽在这张表情中了) 题目链接:http://poj.org/problem?id=163 ...

随机推荐

  1. Sphinx 排序模式 SetSortMode

    可使用如下模式对搜索结果排序: SPH_SORT_RELEVANCE 模式, 按相关度降序排列(最好的匹配排在最前面) SPH_SORT_ATTR_DESC 模式, 按属性降序排列 (属性值越大的越是 ...

  2. Day14 html简介

    初识html <!DOCTYPE html> <html lang="en"> <head> <!--自闭合标签--> <me ...

  3. operation 多线程

    2.Cocoa Operation 优点:不需要关心线程管理,数据同步的事情.Cocoa Operation 相关的类是 NSOperation ,NSOperationQueue.NSOperati ...

  4. 转:PHP非阻塞模式

    你可以任意转摘“PHP非阻塞模式”,但请保留本文出处和版权信息.作者:尘缘,QQ:130775,来源:http://www.4wei.cn/archives/1002336 让PHP不再阻塞当PHP作 ...

  5. mapreduce (五) MapReduce实现倒排索引 修改版 combiner是把同一个机器上的多个map的结果先聚合一次

    (总感觉上一篇的实现有问题)http://www.cnblogs.com/i80386/p/3444726.html combiner是把同一个机器上的多个map的结果先聚合一次现重新实现一个: 思路 ...

  6. Node.js回调概念

    什么是回调? 回调是一个异步等效的功能.在完成特定任务回调函数被调用. Node大量使用了回调.Node的所有的API都支持回调这样的一种方式. 例如,一个函数读取一个文件可能开始读取文件,并使得下一 ...

  7. UBUNTU下FPT工具--lftp使用说明

    lftp 是UBUNTU下一个功能强大的下载工具,它支持访问文件的协议: ftp, ftps, http, https, hftp, fish.(其中ftps 和https需要在编译的时候包含open ...

  8. php socket 通信

    Socket扩展是基于流行的BSD sockets,实现了和socket通讯功能的底层接口,它可以和客户端一样当做一个socket服务器. 想了解更通用的客户端socket接口,请看 stream_s ...

  9. 整合apache+tomcat+keepalived实现高可用tomcat集群

    Apache是一个强大的Web服务器在处理静态页面.处理大量网络客户请求.支持服务的种类以及可配置方面都有优势,高速并且强壮.但是没有JSP/Servlet的解析能力.整合Apache和Tomcat可 ...

  10. 详解udev

    如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Linux改变了几次策略.在Linux早期,设备文件仅仅是是一些带有适当的属性集的普通文件,它由mknod命令创建,文件存放在/dev ...