UVA 10129 Play on Words (欧拉通路)

题意:

  输入N(N <= 100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同(例如:acm,malform,mouse)。每个单词最多包含 1000 个小写字母。输入中可以有重复的单词。

思路:

  把一个字母的两端开成节点,单词看成有向边,若问题有借,当且仅当图中存在欧拉通路。所有只需要判断由单词而构建的图是否存在欧拉通路,由于是有向边,所以利用有向图欧拉通路的判定就可以了。

判定条件

(1):底图是连通图

(2):可以有两个奇点,其中一个出度比入度大 1,另外一个入度比出度大1.

对于条件1,在这里用并查集判断了,条件2统计每个点的出度,入度,加以判断就行了.

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;  

const int maxV = 29;
int m;
int pre[maxV + 7];
int outdegree[maxV + 7];
int indegree[maxV + 7];

int Find(int x){return x == pre[x] ? x : pre[x] = Find(pre[x]); }//并查集的查找
void initPre(){ for(int i = 0; i <= maxV; i++) pre[i] = i; }//初始化并查集的数组

int mix(int x, int y)//并查集的合并
{
    int fx = Find(x), fy = Find(y);
    if(fx != fy) pre[fx] = fy;
}

bool isConnct()//判断图是否连通,即所有的点都在一个集合里面
{
    int cnt = 0;
    for(int i = 1; i <= maxV; i++)if( (outdegree[i] != 0 || indegree[i] != 0) && pre[i] == i) cnt++;
    if(cnt == 1)return true;
    return false;
}

bool isEulur()//是否存在欧拉通路
{
    int cnt = 0;
    int flag = 0;
    for(int i = 1; i <= 26; i++)
        if((outdegree[i] != 0 || indegree[i] != 0) && (indegree[i] != outdegree[i]))//判断奇点,方法不唯一。
        {
            cnt++;
            flag += (indegree[i] - outdegree[i]);
            if(flag > 1 || flag < -1) return false;
        }
    if(cnt == 0 || cnt == 2 && flag == 0) return true;
    return false;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &m);
        initPre();
        memset(indegree, 0, sizeof(indegree));
        memset(outdegree, 0, sizeof(outdegree));
        for(int i = 1; i <= m; i++)
        {
            char word[1000 + 7];
            scanf("%s", word);
            int u = word[0] - ‘a‘ + 1;
            int len = strlen(word);
            int v = word[len - 1] - ‘a‘ + 1;
            mix(u, v);
            ++outdegree[u];
            ++indegree[v];
        }
        if(isEulur() && isConnct())    printf("Ordering is possible.\n");
        else                        printf("The door cannot be opened.\n");
    }
    return 0;
}
时间: 2024-10-29 04:29:42

UVA 10129 Play on Words (欧拉通路)的相关文章

HDU 5883 F - The Best Path 欧拉通路 &amp; 欧拉回路

给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值. 首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为是回路,所以你的开始点就会被访问多一次,所以如果是欧拉回路的话,还需要O(n)扫一次,枚举每个点作为起点. 欧拉通路的话,结果是固定的,因为只能从奇数度小的那个点作为起点,奇数度大的那个点作为终点. 关于点的访问次数:anstime  = Degree[i] / 2; //如果是奇数的,还要加上一.

关于欧拉通路、欧拉回路的一些定理,推论

关于欧拉通路.欧拉回路的一些定义: 无向图:G是一个连通的无向图(1)经过G的每条边一次并且仅一次的路径为欧拉通路(起点和终点不一定要一样).(2)如果欧拉通路是回路(起点和终点是同一个),则为欧拉回路.(3)具有欧拉回路的无向图G称为欧拉图. 有向图:D是一个有向图,D的基图(把D的有向边改为无向边)是连通的(1)经过D的每条边一次并且仅一次的路径称为有向欧拉通路(起点和终点不一定一样).(2)如果有向欧拉通路是回路(起点和终点一样),那么称为有向欧拉通路.(3)具有有向欧拉通路的有向图D称为

图论——欧拉通路、欧拉回路(有向图无向图混合图)

之前稍微了解有向图.无向图.混合图的欧拉通路.欧拉回路,这里做下笔记,以便日后翻阅. 无向图: 存在欧拉回路的条件:原图连通,每个结点均为偶度结点. 存在欧拉通路的条件:存在欧拉回路,或原图连通,有两个结点为奇度结点,其他结点均为偶度结点. 有向图: 存在欧拉回路的条件:基图连通,每个结点的入度等于出度. 存在欧拉通路的条件:存在欧拉回路,或基图连通,有一个结点入度等于出度+1,有一个结点出度等于入度+1,其他结点的入度等于出度. 混合图: 存在欧拉回路的条件: 1.将无向边随便定向,每个结点的

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

题意  见下方中文翻译 每一个单词能够看成首尾两个字母相连的一条边  然后就是输入m条边  推断是否能构成有向欧拉通路了 有向图存在欧拉通路的充要条件: 1. 有向图的基图连通: 2. 全部点的出度和入度相等  或者  仅仅有两个入度和出度不相等的点  且这两点入度与出度的差一个为-1(起点)一个为1(终点). 推断是否连通就是应用并查集了 #include<cstdio> #include<cstring> using namespace std; const int N = 3

poj 2513 Colored Sticks(欧拉通路+并查集+字典树)

题目链接:poj 2513 Colored Sticks 题目大意:有N个木棍,每根木棍两端被涂上颜色,现在给定每个木棍两端的颜色,不同木棍之间拼接需要颜色相同的 端才可以,问最后能否将N个木棍拼接在一起. 解题思路:欧拉通路+并查集+字典树.欧拉通路,每个节点的统计度,度为奇数的点不能超过2个.并查集,判断节点 是否完全联通.字典树,映射颜色. #include <cstdio> #include <cstring> #include <string> #includ

POJ2513Colored Sticks(欧拉通路)(字典树)(并查集)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 35612   Accepted: 9324 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a st

poj2513Colored Sticks(欧拉通路+字典树+并查集)

Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color? Input Input is a

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

题目大意: 有一堆头尾均有颜色的木条,要让它们拼接在一起,拼接处颜色要保证相同,问是否能够实现 这道题我一开始利用map<string,int>来对颜色进行赋值,好进行后面的并查操作以及欧拉通路的判断,但是map效率太低,超时了 网上看了一遍发现必须得用效率更高的字典树对每个不同的颜色进行赋值 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace st

一笔画问题 南阳oj42 【并查集+欧拉通路的判断】

描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来. 规定,所有的边都只能画一次,不能重复画. 输入 第一行只有一个正整数N(N<=10)表示测试数据的组数. 每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<=2000),分别表示这个画中有多少个顶点和多少条连线.(点的编号从1到P) 随后的Q行,每行有两个正整数A,B(0<A,B<P),表示编号为A和B的两点之间有连线. 输出 如果存在符合条件的连线

ACM/ICPC 之 DFS求解欧拉通路路径(POJ2337)

判断是欧拉通路后,DFS简单剪枝求解字典序最小的欧拉通路路径 //Time:16Ms Memory:228K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MAX 1005 #define MAXS 24 //姓名 #define MAXN 26 //字母 struct Edge{ char name