1126 Eulerian Path (25分)

1126 Eulerian Path (25分)

In graph theory, an Eulerian path is a path in a graph which visits every edge exactly once. Similarly, an Eulerian circuit is an Eulerian path which starts and ends on the same vertex. They were first discussed by Leonhard Euler while solving the famous Seven Bridges of Konigsberg problem in 1736. It has been proven that connected graphs with all vertices of even degree have an Eulerian circuit, and such graphs are called Eulerian. If there are exactly two vertices of odd degree, all Eulerian paths start at one of them and end at the other. A graph that has an Eulerian path but not an Eulerian circuit is called semi-Eulerian. (Cited from https://en.wikipedia.org/wiki/Eulerian_path)

Given an undirected graph, you are supposed to tell if it is Eulerian, semi-Eulerian, or non-Eulerian.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N (≤ 500), and M, which are the total number of vertices, and the number of edges, respectively. Then M lines follow, each describes an edge by giving the two ends of the edge (the vertices are numbered from 1 to N).

Output Specification:

For each test case, first print in a line the degrees of the vertices in ascending order of their indices. Then in the next line print your conclusion about the graph – either Eulerian, Semi-Eulerian, or Non-Eulerian. Note that all the numbers in the first line must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input 1:
7 12
5 7
1 2
1 3
2 3
2 4
3 4
5 2
7 6
6 3
4 5
6 4
5 6
Sample Output 1:
2 4 4 4 4 4 2
Eulerian
Sample Input 2:
6 10
1 2
1 3
2 3
2 4
3 4
5 2
6 3
4 5
6 4
5 6
Sample Output 2:
2 4 4 4 3 3
Semi-Eulerian
Sample Input 3:
5 8
1 2
2 5
5 4
4 1
1 3
3 2
3 4
5 3
Sample Output 3:
3 3 4 3 3
Non-Eulerian
题意:

如果一个连通的无向图的所有顶点的度都为偶数,则该图存在欧拉回路,称这样的图为Eulerian;如果一个连通的无向图的所有顶点的度恰好有两个为奇数,则存在从其中一个度为奇数的顶点到另一个度为奇数的顶点的欧拉路径,但是没有欧拉回路,这样的图称之为semi-Eulerian;否则为non-Eulerian;给定一个无向图,判断其为以上三种中的哪一种,先输出每个顶点的度,然后输出图的类型;

分析:

用邻接表存储该图,用一个数组保存所有顶点的度,然后计算顶点度为奇数和偶数的顶点个数,最后进行深度优先搜索判断该图是否连通;

题解:
#include <iostream>
#include <vector>
using namespace std;
vector<int> vec[510];
int degree[510]{ 0 }, visited[510]{0};
void dfs(int j) {
	visited[j] = 1;
	for (int k = 0; k < vec[j].size(); k++) {
		if (!visited[vec[j][k]])
			dfs(vec[j][k]);
	}
}
int main() {
	int n,m,evens=0,odds=0;
	scanf("%d%d", &n,&m);
	for (int i = 0; i < m; i++) {
		int u, v;
		scanf("%d%d", &u, &v);
		vec[u].push_back(v);
		vec[v].push_back(u);
		degree[u]++;
		degree[v]++;
	}
	for (int i = 1; i <= n; i++) {
		if (degree[i] % 2 == 0)
			evens++;
		else
			odds++;
		if (i != 1) printf(" ");
		printf("%d", degree[i]);
	}
	int k = 0;
	for (int i = 1; i <= n; i++) {
		if (!visited[i]) {
			dfs(i);
			k++;
		}
	}
	if (n) printf("\n");
	if (k==1 && evens == n)
		printf("Eulerian\n");
	else if(k==1 && odds == 2)
		printf("Semi-Eulerian\n");
	else
		printf("Non-Eulerian\n");
	return 0;
}
七桥问题,又称柯尼斯堡七桥问题,是图论中一个著名的问题。问题的背景是普雷戈利亚河穿过柯尼斯堡,形成两个岛,并且河岸和岛之间有七座桥连接。问题在于是否存在一条路径,可以恰好经过每座桥一次并且回到起点。 图论的创始人欧拉在1736年证明了这个问题的不可能性,并且提出了欧拉路径的概念,即一个图中经过每条边恰好一次的路径。一个图存在欧拉路径的条件是:图是连通的,并且有0个或2个顶点的度数为奇数(这些顶点被称为欧拉端点)。如果一个图的每个顶点的度数都是偶数,则存在欧拉回路,即从某一点出发,经过每条边恰好一次后可以回到起点的路径。 以下是一个使用Python编写的简单代码示例,用于检测给定的图是否包含欧拉路径或欧拉回路,并尝试输出一条欧拉路径或回路(如果存在的话)。 ```python from collections import defaultdict # 创建图 def create_graph(edges): graph = defaultdict(list) for edge in edges: graph[edge[0]].append(edge[1]) graph[edge[1]].append(edge[0]) return graph # 检查是否是欧拉图并返回路径 def find_eulerian_path(graph): # 计算每个顶点的度数 degrees = {vertex: len(graph[vertex]) for vertex in graph} # 找到所有度数为奇数的顶点 odd_degree_vertices = [vertex for vertex, degree in degrees.items() if degree % 2 == 1] # 检查是否是欧拉图 if odd_degree_vertices and len(odd_degree_vertices) not in [0, 2]: return None # 如果有超过两个顶点度数为奇数,则不存在欧拉路径 # 如果所有顶点的度数都是偶数,则是欧拉回路 if not odd_degree_vertices: # 从任意顶点开始遍历 start_vertex = list(graph.keys())[0] eulerian_path = [start_vertex] current_vertex = start_vertex while len(graph[current_vertex]) > 0: next_vertex = graph[current_vertex].pop() eulerian_path.append(next_vertex) current_vertex = next_vertex return eulerian_path # 如果有两个顶点度数为奇数,则存在欧拉路径 else: # 从任意一个度数为奇数的顶点开始遍历 start_vertex = odd_degree_vertices[0] eulerian_path = [start_vertex] current_vertex = start_vertex while len(graph[current_vertex]) > 0: next_vertex = graph[current_vertex].pop() eulerian_path.append(next_vertex) current_vertex = next_vertex return eulerian_path # 示例图的边 edges = [('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('C', 'E'), ('D', 'E')] graph = create_graph(edges) eulerian_path = find_eulerian_path(graph) print("Eulerian path: ", eulerian_path) ``` 请根据你的具体需求调整边的列表。注意,这个程序只能处理简单的图,并且假设图是无向的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值