无向图与有向图判定欧拉道路与欧拉回路的方法

欧拉道路:

从无向图中的一个节点出发走一条道路,每条边恰好经过一次,这样的线路成为欧拉道路。

下面给出欧拉道路的判定方法:

有向图:

图必须是连通的,而且最多只能有两个点入度不等于出度,而且这两个点其中一个点的入度+1=出度,另一个点的出度+1=入度,如果有的点出度!=入度&&出度与入度的绝对值差还不等于1,则这个图不是欧拉道路。

无向图:

图必须是连通的,而且最多有两个奇度点,则是欧拉道路。

判定图连通的方法:

无向图用dfs访问,看看点是否全部被访问。

有向图先转化为无向图,然后再用dfs判定。

欧拉回路:

如果一个回路是欧拉路径,则称为欧拉回路。

下面给出欧拉回路的判定方法:

有向图:

图连通,且所有顶点的入度等于出度。

无向图:

图连通,且没有奇度点。

下面给出一个欧拉道路的例题:

题目为UVa的10129:

题目:

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 important for us.

There is a large number of magnetic plates on every door. Every plate has one word written on it. The plates must be arranged into a sequence in such a way that every word begins with the same letter as the previous word ends. For example, the word ``acm‘‘ can be followed by the word ``motorola‘‘. Your task is to write a computer program that will read the list of words and determine whether it is possible to arrange all of the plates in a sequence (according to the given rule) and consequently to open the door.

题目大意翻译:

有一些秘密的门包含着非常有趣的单词迷题, 考古学家队伍必须解决它们才能够打开大门。 因为没有其他方法能偶打开这些门, 所以解决那些迷题对我们非常重要。

在每个门上有很多个有磁力的盘子,盘子上面写着单词。 必须重新移动放置这些盘子,让它们形成一个队列:队列中,除了第一个单词,每个单词的开头和上一个单词的结尾字母

一样。例如, motorola的后面可以接上acm。

你的任务是写一个程序, 读入一系列单词,然后计算确定它们是否有可能被排成这样的队列。

样例输入:

3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok

样例输出:

The door cannot be opened.
Ordering is possible.
The door cannot be opened.

思路:

可以把首尾字母看做节点,把单词看成有向边,构造有向图,如果有解,当且仅当图中有欧拉路径。

上面说到了有向图的欧拉路径的判定方法:1.将有向图转化为无向图判定连通,2.看入度和出度的关系。

代码如下:

#include <cstdio>
#include <cstring>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=30;
int n,t;
int in[30],out[30];
int edge[maxn][maxn];
int vis[maxn];
//dfs判定连通
void dfs (int x)
{
    vis[x]=1;
    for (int i=0;i<26;i++)
    {
        if(edge[x][i]&&!vis[i])
        {
            dfs(i);
        }
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        memset (in,0,sizeof(in));
        memset (out,0,sizeof(out));
        memset (edge,0,sizeof(edge));
        memset (vis,0,sizeof(vis));
        scanf("%d",&n);
        for (int i=0;i<n;i++)
        {
            char x[1005];
            scanf("%s",x);
            int len=strlen(x);
            //构造无向图
            edge[x[0]-‘a‘][x[len-1]-‘a‘]++;
            edge[x[len-1]-‘a‘][x[0]-‘a‘]++;
            //构造有向图的入度和出度关系
            out[x[0]-‘a‘]++;
            in[x[len-1]-‘a‘]++;
        }
        int edge=0,num1=0,num2=0,Flag=1;
        //根据入度出度判定是否满足条件
        for (int i=0;i<=26;i++)
        {
            if(in[i]!=out[i])
            {
                if(in[i]-out[i]==1) num1++;
                else if(in[i]-out[i]==-1) num2++;
                else
                {
                    Flag=0;
                    break;
                }
            }
        }
        if(num1&&num2&&num1+num2>2) Flag=0;
        if(Flag==0)
        {
            printf("The door cannot be opened.\n");
            continue;
        }
        //判定连通
        for (int i=0;i<=26;i++)
        {
            if(out[i]||in[i])
            {
                dfs(i);
                break;
            }
        }
        int flag=0;
        for (int i=0;i<=26;i++)
        {
            if(in[i]&&!vis[i]){flag=1; break;}
            if(out[i]&&!vis[i]){flag=1;break;}
        }
        if(flag==0) printf("Ordering is possible.\n");
        else printf("The door cannot be opened.\n");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xfy9/p/10454504.html

时间: 2024-11-05 15:57:37

无向图与有向图判定欧拉道路与欧拉回路的方法的相关文章

无向图欧拉道路(欧拉回路)的判定与路径打印

欧拉道路描述的是无向图的一个顶点出发的一条道路能够经过每条边恰好一次 欧拉回路指的是任意点出发都满足上述性质 如果一个图是欧拉道路或者欧拉回路,必须满足两个条件 第一个条件,这个图是连通图 第二个条件,所有点的度数满足"一定的关系" 然后我们阐述一下"一定的关系"是什么 检查这个图所有点的度数,求出这个图度数给奇数的点的个数,我们也可以称之为奇点数 如果没有奇点,这个图是一个欧拉回路,从任意点出发可以经过所有的边并回到这个点 如果存在两个奇点(这两个奇点具有这样的性

欧拉道路与欧拉回路

欧拉道路与欧拉回路 欧拉道路:通过图G中每条边一次且仅一次的道路称作该图的欧拉道路. 欧拉回路:通过图G中每条边一次且仅一次的回路称作该图的欧拉回路. 欧拉图:存在欧拉回路的图称为欧拉图. 欧拉在1736年给出了欧拉道路/回路存在的必要条件,在1873年希尔霍尔策首次给出了刻画欧拉图的充要条件. 定理 (a)无向图G是欧拉图(存在欧拉回路)当且仅当G是连通的且所有顶点都是偶数度 (b)无向图G存在欧拉道路当且仅当G是连通的且奇数度顶点不超过2个 下面证明(a): 1.(必要性)如果是欧拉图,从一

UVa 10129 Play On Words【欧拉道路 并查集 】

题意:给出n个单词,问这n个单词能否首尾接龙,即能否构成欧拉道路 按照紫书上的思路:用并查集来做,取每一个单词的第一个字母,和最后一个字母进行并查集的操作 但这道题目是欧拉道路(下面摘自http://blog.csdn.net/hcbbt/article/details/9316301) 关于欧拉道路(from Titanium大神): 判断有向图是否有欧拉路 1.判断有向图的基图(即有向图转化为无向图)连通性,用简单的DFS即可.如果图都不连通,一定不存在欧拉路 2.在条件1的基础上   对于

dfs求欧拉道路

从一个节点出发的一条路径每条边只经过一次,则把这条路称作欧拉道路. 欧拉道路存在着这样的性质除起点和终点以外所有经过的节点的出度和入度相等,也就是说除起点和终点以外的节点的度都为偶数. 同时一个无向图是连通的,且最多存在两个奇点,则一定存在欧拉道路,并且如果是有两个奇点,欧拉道路一定是从一个奇点出发到达另外一个奇点,如果没有奇点,则从任何一个节点出发然后最终回到该点(欧拉回路),奇点为一的情况是不存在的. 对于存在欧拉道路的情况,最多只能有两个点的入度不等于出度,而且必须是其中一个节点的入度比出

luogu P2731 骑马修栅栏 Riding the Fences | 欧拉道路

luogu P2731 骑马修栅栏 Riding the Fences luogu P1341 无序字母对 度数:一个点上连接边的个数 1.欧拉道路:相当于一笔画 无向图:除了两个或没有点为奇点(度数为奇)以外,其余度数均为偶 有向图:只有两个点或没有点入度不等于出度,起点入度=出度-1,终点入度=出度+1 2.欧拉回路: 无向图:奇点个数为0 有向图:所有点出度=入度(起点终点重合) #include<cstdio> #include<iostream> using namesp

UVA 10129 Play on Words(欧拉道路)

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

UVA-10129 Play on Words (判断欧拉道路的存在性)

题目大意:给出一系列单词,当某个单词的首字母和前一个单词的尾字母相同,则这两个单词能链接起来.给出一系列单词,问是否能够连起来. 题目分析:以单词的首尾字母为点,单词为边建立有向图,便是判断图中是否存在欧拉道路.有向图中存在欧拉路径的两个条件是:1.忽略边的方向性后,底图联通:2.奇点个数为0时.奇点个数为2并且满足起点的入度比出度小1和终点的出度比入度大1时,欧拉道路一定存在: 判断图的连通性有两种方法:1.利用并查集,只判断有几个根节点即可:2.使用DFS,做法实质上就是判断联通块的个数:

NYOJ 99单词拼接(有向图的欧拉(回)路)

1 /* 2 NYOJ 99单词拼接: 3 思路:欧拉回路或者欧拉路的搜索! 4 注意:是有向图的!不要当成无向图,否则在在搜索之前的判断中因为判断有无导致不必要的搜索,以致TLE! 5 有向图的欧拉路:abs(In[i] - Out[i])==1(入度[i] - 出度[i])的节点个数为两个 6 有向图的欧拉回路:所有的节点都有In[i]==Out[i] 7 */ 8 #include<iostream> 9 #include<cstring> 10 #include<cs

UVA 10441 - Catenyms(欧拉道路)

UVA 10441 - Catenyms 题目链接 题意:给定一些单词,求拼接起来,字典序最小的,注意这里的字典序为一个个单词比过去,并非一个个字母 思路:欧拉回路.利用并查集判联通,然后欧拉道路判定,最后dfs输出路径 代码: #include <cstdio> #include <cstring> #include <string> #include <vector> #include <iostream> #include <algo