数据结构PTA习题:案例6-1.3 哥尼斯堡的“七桥问题” (25分)

案例6-1.3 哥尼斯堡的“七桥问题” (25分)

哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,如下图所示。
在这里插入图片描述
可否走过这样的七座桥,而且每桥只走过一次?瑞士数学家欧拉(Leonhard Euler,1707—1783)最终解决了这个问题,并由此创立了拓扑学。
这个问题如今可以描述为判断欧拉回路是否存在的问题。欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个无向图,问是否存在欧拉回路?

输入格式:
输入第一行给出两个正整数,分别是节点数N (1≤N≤1000)和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。

输出格式:
若欧拉回路存在则输出1,否则输出0。

输入样例1:

6 10
1 2
2 3
3 1
4 5
5 6
6 4
1 4
1 6
3 4
3 6

输出样例1:

1

输入样例2:

5 8
1 2
1 3
2 3
2 4
2 5
5 3
5 4
3 4

输出样例2:

0

这道题我最开始的思路是:对每条边增加一个标记,记录该边是否走过。看最后能否实现走过了所有的边后回到最初点。
用这种思路编程,前三个测试点都能通过,最后两个测试点运行超时。
后来在网上看到了别人的一篇博客(原文链接https://blog.csdn.net/treblez/article/details/100996249):
存在欧拉回路需满足两个条件:
1.无向图连通
2.所有结点的度全部为偶数
我用邻接矩阵存储无向图。
判断无向图连通我是先深度优先搜索DFS遍历图,再遍历Visited数组,判断是否所有的结点都被访问过。如果所有结点都被访问过,则无向图连通;否则,不连通,不存在欧拉回路。
再对每个结点逐个判断度是否为偶数,求出某结点的邻接矩阵对应行中的非零元素总个数,若为奇数,则不存在欧拉回路;若所有结点的度均为偶数,且图连通,则存在欧拉回路。

C语言实现:

#include<stdio.h>
#include<stdlib.h>
struct edge
{
	int vs;
	int ve;
};
typedef struct edge * Edge;
struct graph //邻接矩阵存储图
{
	int Nv;
	int Ne;
	int * * M;
};
typedef struct graph * Graph;
Graph CreateGraph(int N);
void DFS(Graph G, int i);
int * Visited;
int main()
{
	int i;
	int N, M;
	scanf("%d %d", &N, &M);
	Visited = (int *)malloc(N * sizeof(int));
	for (i = 0; i < N; i++)
	{
		Visited[i] = 0;
	}
	Graph G;
	G = CreateGraph(N);
	G->Ne = M;
	int v1, v2;
	int yes;
	Edge * e;
	e = (Edge *)malloc(M * sizeof(Edge));
	for (i = 0; i < M; i++)
	{
		e[i] = (Edge)malloc(sizeof(struct edge));
	}
	for (i = 0; i < M; i++)
	{
		scanf("%d %d", &v1, &v2);
		e[i]->vs = v1 - 1;
		e[i]->ve = v2 - 1;
		G->M[v1 - 1][v2 - 1] = 1;
		G->M[v2 - 1][v1 - 1] = 1;
	}
	//判断图是否连通
	DFS(G, 0); //深度优先搜索DFS遍历图
	for (i = 0; i < N; i++)
	{
		if (Visited[i] == 0) { yes = 0; break; }//是否有未访问的结点
	}
	if (i == N)
	{
		//判断各结点的度是否均为偶数
		yes = 1;
		int j;
		int du = 0;//记录结点的度
		for (i = 0; i < N; i++)
		{
			du = 0;
			for (j = 0; j < N; j++)
			{
				if (G->M[i][j] == 1)
				{
					du++;
				}
			}
			if (du % 2 == 1)
			{
				yes = 0;
				break;
			}

		}
	}
	if (yes == 1) { printf("1"); }
	else { printf("0"); }
	return 0;
}
Graph CreateGraph(int N) //创建图
{
	int i, j;
	Graph G;
	G = (Graph)malloc(sizeof(struct graph));
	G->Nv = N;
	G->M = (int * *)malloc(N * sizeof(int *));
	for (i = 0; i < N; i++)
	{
		G->M[i] = (int *)malloc(N * sizeof(int));
	}
	for (i = 0; i < N; i++)
	{
		for (j = 0; j < N; j++)
		{
			G->M[i][j] = 0;
		}
	}
	return G;
}
void DFS(Graph G, int i) //深度优先搜索遍历
{
	int j;
	Visited[i] = 1;
	for (j = 0; j < G->Nv; j++)
	{
		if (G->M[i][j] == 1 && Visited[j] == 0)
		{
			DFS(G, j);
		}
	}
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
尼斯七桥问题是一个经典的数学问题,它的解决由瑞士数学家欧拉完成,并由此创立了拓扑学。该问题描述了一个位于普雷格河上的城市尼斯,包含两个岛屿和七座桥。问题要求通过这七座桥一次且仅一次地走过所有的桥。 要解决这个问题,可以使用并查集来判断图是否连通,或者使用BFS(广度优先搜索)的方法进行判断。首先,我们需要将桥和岛屿之间的关系表示为图的形式,然后判断图是否连通。如果图连通,并且每个节点的度数都是偶数,那么就存在一条满足要求的路径。 举例来说,假设有六座桥和六个岛屿,编号别为1、2、3、4、5、6。如果桥的连接情况如输入样例1所示:1-2、2-3、3-1、4-5、5-6、6-4、1-4、1-6、3-4、3-6,我们可以使用并查集或BFS来判断图是否连通。如果图是连通的,并且每个节点的度数都是偶数,那么就可以走过每座桥一次且仅一次。 因此,数据结构尼斯七桥问题即为通过判断图的连通性和节点的度数来确定是否存在一条满足要求的路径。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [PTA数据结构与算法 7-32 尼斯的“七桥问题”](https://blog.csdn.net/qq_43362828/article/details/90181888)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值