欧拉回路的判断

基础概念

首先来看一下离散数学中的一些基础概念:
通路:在无向图中由点边交替组成的序列就是通路(如果这个图是简单的,那么也可以使用点的序列来表示),如果首尾的点相同,则称为一条回路
无向图的连通性:无向图中任意一对点之间均有通路
欧拉通路:从某个顶点出发,将所有的边遍历一遍并且仅经过一遍的通路序列称为欧拉通路,连通的多重图有欧拉回路而无欧拉回路当且仅当它恰有两个奇数度顶点
这里说明了欧拉通路的条件:

  • 图是连通的,没有孤立节点
  • 对于无向图来说,奇数度的顶点为2个,这两个顶点分别是起点以及终点(0个的话就是回路了)

欧拉回路:如果欧拉通路的起点与终点一样,则成为欧拉回路, 连通的多重图具有欧拉回路当且仅当它的每个顶点都有偶数度
则欧拉回路的条件:

  • 图是连通的,没有孤立节点
  • 无向图的每个节点的度数都是偶数度,有向图每个节点的入度等于出度

判断图是否存在欧拉回路

根据判断的条件,首先是判断图的连通性,然后判断图的每个节点的度数是否是偶数就可以了:

例如,这个题目:

链接:https://www.nowcoder.com/questionTerminal/0ba5d8f525494a8787aaa9d53b5f9b9e
来源:牛客网

输入描述:

测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结束。

输出描述:

每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
示例1
输入

3 3
1 2
1 3
2 3
3 2
1 2
2 3
0
输出

1
0

代码

#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define N 1005
int n,m;
int a,b;
int degree[N];
int tree[N];

int findroot(int x){               //并查集的方式判断图连通性
    if(tree[x]==-1)
        return x;
    else{
        int temp = findroot(tree[x]);
        tree[x] = temp;
        return temp;
    }
}
int main(){
    while(cin>>n && n){
        cin>>m;
        memset(tree, -1, sizeof(tree));
        memset(degree, 0, sizeof(degree));
        for(int i=0; i<m; i++){
            cin>>a>>b;
            int tempa = findroot(a);
            int tempb = findroot(b);
            if(tempa != tempb)
                tree[tempa] = tempb;
            degree[a]++;                //无向图记录度数
            degree[b]++;
        }
        int flag = 0;
        int ans = 0;
        for(int i=1; i<= n; i++){     //判断连通性
            if(tree[i]==-1)
                ans++;
        }
        for(int i=1; i<=n; i++){    //判断度数
            if(degree[i]%2){
                flag = 1;
                break;
            }
        }
        if(ans > 1 || flag)
            cout<<"0"<<endl;
        else
            cout<<"1"<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_34328764/article/details/80362444