Play on Words UVA - 10129 (欧拉回路)

题目链接:https://vjudge.net/problem/UVA-10129

题目大意:输入N  代表有n个字符串  每个字符串最长1000  要求你把所有的字符串连成一个序列  每个字符串的第一个字母是前一个字符串的最后一个字母

思路:这是学的欧拉回路的第一道题 ,把单词的首字母和尾字母看做结点,单词看作边 ,判断能否找出一条欧拉回路就行了

首先要知道什么是欧拉回路:

第一个条件:图必须是连通的

第二个条件:最多只有两个奇点(出度和入度不相等的点)

满足上面两个条件的就是欧拉回路

如果有两个奇点,必须从一个奇点出发 另一个奇点终止。  不存在奇点的话  任一点出发  回到该点

注意:图是连通的是前提。

求欧拉回路有两种做法  一种是dfs  一种是并查集

我两种都写了,但是用dfs的做法  一直wa   到现在也不明白错在哪了。  所以这里就列出并查集的做法吧

#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
const int maxn=1000+5;
int pa[256];
int findset(int x)//找到它的祖先
{
    if(pa[x]==x) return pa[x];
    return pa[x]=findset(pa[x]);
}

int used[256],deg[256];//是否出现过  度数

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        char word[maxn];
        cin>>n;
        memset(used,0,sizeof(used));
        memset(deg,0,sizeof(deg));
        for(int ch=‘a‘;ch<=‘z‘;ch++) pa[ch]=ch;//初始化并查集
        int cc=26;//连通块个数

        for(int i=0;i<n;i++)
        {
            cin>>word;
            char c1=word[0],c2=word[strlen(word)-1];
            deg[c1]++;//出度的话 ++
            deg[c2]--;//入度  --
            used[c1]=used[c2]=1;//标记为出现过
            int s1=findset(c1),s2=findset(c2);//找到他们的祖先
            if(s1!=s2)//不是同一个祖先
            {
                pa[s1]=s2;
                cc--;//连通块减一
            }
        }
        vector<int> d;
        for(int ch=‘a‘;ch<=‘z‘;ch++)
        {
            if(!used[ch]) cc--;//没出现过的字母
            else if(deg[ch]!=0) d.push_back(deg[ch]);//出度和入度不相等的结点
            //=0代表出度和入度相等的结点 不需要考虑
        }
        bool ok=false;
        if(cc==1&&(d.empty()||(d.size()==2&&(d[0]==1||d[0]==-1)))) ok=true;//cc=1代表只剩下一个块   为空代表成环  不为空 为2的话 一个是出度一个是入度
        if(ok) cout<<"Ordering is possible."<<endl;
        else cout<<"The door cannot be opened."<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/caijiaming/p/10390426.html

时间: 2024-11-23 13:49:26

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

【紫书】Play on Words UVA - 10129 欧拉回路

题意:给你1e5个字符串,若前一个的末尾字母等于当前的首字母,则可以连在一起(成语接龙一个意思)判断是否可以将他们连在一起 题解:将首位看作点,单词看作边.变成欧拉回路问题. 判断出入度是否相等,再用并查集判一下连通性 (dfs/bfs也行:随便取一个点,搜索一遍.如果每个点都被标记,则是连通的.) ac代码: #define _CRT_SECURE_NO_WARNINGS #include "stdio.h" #include<stdio.h> #include<a

Play on Words UVA - 10129 欧拉路径

关于欧拉回路和欧拉路径 定义:欧拉回路:每条边恰好只走一次,并能回到出发点的路径欧拉路径:经过每一条边一次,但是不要求回到起始点 ①首先看欧拉回路存在性的判定: 一.无向图每个顶点的度数都是偶数,则存在欧拉回路. 二.有向图(所有边都是单向的)每个节顶点的入度都等于出度,则存在欧拉回路. ②.欧拉路径存在性的判定 一.无向图一个无向图存在欧拉路径,当且仅当   该图所有顶点的度数为偶数   或者  除了两个度数为奇数外其余的全是偶数. 二.有向图一个有向图存在欧拉路径,当且仅当  该图所有顶点的

Play on Words UVA - 10129 (有向图欧拉路径)

Play on Words UVA - 10129 题意:n个单词,问能否收尾相连形成一条链. 把单词首尾字母看做点,单词内部连一条边,问是否存在欧拉路径. 用并查集,当且仅当只有一个点的出度比入度大1一个点的入度比出度大1其它点出度和入度相等时存在欧拉路径. 1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 #include<iostream> 5 #include<cctype>

uva 10129 Play on Words(欧拉路)

uva 10129 Play on Words Description Play on Words Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other way to open the doors, the puzzle is very impo

UVA - 10129 Play on Words(欧拉回路+并查集)

2.解题思路:本题利用欧拉回路存在条件解决.可以将所有的单词看做边,26个字母看做端点,那么本题其实就是问是否存在一条路径,可以到达所有出现过的字符端点.由于本题还要求了两个单词拼在一起的条件是前一个单词的右端点和本单词的左端点一样.所以这是一个有向图.根据结论:有向图的底图(忽略边的方向后的图)必须连通:有向图中最多只能有两个端点的入度不等于出度,且必须是其中一点的入度比出度小1,另一点的入度比出度大1.因此先判断端点是否都连通,再判断每个端点的度数是否满足结论即可. 那么,如何判断连通性呢?

Play on Words,UVA 10129——求欧拉回路/欧拉通路

Play on words 紫书上的一道题: 输入n(n<=100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同.每个单词最多包含1000个小写字母.输入中可以有重复单词. 分析: 把字母看成结点,单词看成有向边,则问题有解,当且仅当图中存在欧拉通路/欧拉回路 欧拉通路/回路:通过图中所有边一次且仅一次行遍所有顶点的通路/回路 有向图存在欧拉回路的判断条件:当且仅当有向图是强连通的,且没有奇度顶点,所有顶点的入度等于出度 有向图存在欧拉

UVa 10129 单词

题意:给定一些单词,单词的尾字母和另一单词的首字母相同,则可以串联,问是否可以将所有的单词串联.单词可重复出现,但每个单词只能用一次:即某单词重复几次,则可用几次. 思路:欧拉道路的应用.欧拉道路,即"一笔画",从图中一结点出发走一条道路,每条边恰好经过一次. 首先要判断图是连通的. 对于无向图,最多只有两个奇点(度数为奇数).且从一奇点出发,到另一奇点终止:若无奇点,则可从任意点出发,最终定会回到该点(欧拉回路). 对于有向图,最多只能有两个点的入度不等于出度,且必须其中一点的出度恰

Uva(10129)+Uva(10054)

这两道题都是和欧拉图的判定有关,一个是有向图,一个是无向图的欧拉图的判定还有一个是有向图= = 先看10129...我们把单词的首字母看做是入度,最后一个字符看做是初度,那么这道题就变成图中是否存在欧拉回路.判断有向图的条件是该图是连通图和最多最有两个点的出度不等于入度,其实那两个点就是起点和终点,而且必须是其中一个点的入度比出度恰好大1(作为终点),另一个点的出度比它的入度恰好大1(作为起点) 连通图的话我们用并查集来判断,如果该图是连通图的话,那么他们共用祖先= = #include<std

UVA 10129 Play on Words(欧拉道路)

题意:给你n个字符串,问你是否可以出现一条链,保证链中每个字符串的第一个元素与上一个字符串的最后一个元素相同,注意可能重复出现同一个字符串 题解:以每一个字符串第一个元素指向最后一个元素形成一个有向图,判断这个有向图是否可以形成欧拉路就好 注意可能有重边与自环,因此求欧拉路时判断的是是否使用完了所有的边,求起点时注意出度与入度的计算 欧拉道路是从一个点一笔画完整张图(欧拉回路保证回到起点),注意除了起点与终点以外所有的点出度入度相等 起点出度大入度1,终点相反(所有的点出入度相等也可以),根据这