7-3 七桥问题

7-3哥尼斯堡的“七桥问题”(25 分)


小知识(ゝω・)

欧拉回路:如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径。
如果一个回路是欧拉路径,则称为欧拉回路。
具有欧拉回路的图称为欧拉图(简称E图)。具有欧拉路径但不具有欧拉回路的图称为半欧拉图。
所有顶点的度均为偶数的任何连通图必然有欧拉回路。



哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,可否走过这样的七座桥,而且每桥只走过一次?瑞士数学家欧拉(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


代码:


#include<iostream>
#include<cstring>
#include<vector>
#include<queue>


using namespace std;


int flag[1010];
int g[1010][1010];
int path[1010];
int Count = 0;


void DFS(int point,int n) {
	Count++;//定义全局变量count,每调用一次DFS时count+1,如果count等于节点数n,表示所有节点都被遍历了
	for (int i = 1; i <= n; i++) {
		if (g[point][i] == 1 && flag[i] == 0) {
			flag[i] = 1;
			DFS(i,n);
		}
	}
	return;
}


//BFS不需要用递归,所以速度比DFS快
void BFS(int point, int n) {
	queue<int> q;
	q.push(point);
	flag[point] = 1;
	while (!q.empty()) {
		int vertex = q.front();
		q.pop();
		for (int i = 1; i <= n; i++) {
			if (g[vertex][i] == 1 && flag[i] == 0) {
				q.push(i);
				flag[i] = 1;
				//cout << point << " " << i << endl;
			}
		}
	}
}


//bool judge(int n, int flag[]) {
//	for (int i = 1; i <= n; i++) {
//		if (flag[i] == 0) {
//			return false;
//		}
//	}
//	return true;
//}


bool Even(int path[], int n) {
	for (int i = 1; i <= n; i++) {
		if (path[i] % 2 != 0) {
			return false;
		}
	}
	return true;
}


int main() {
	int n, m;
	cin >> n >> m;
	memset(g, 0, sizeof(g));
	memset(flag, 0, sizeof(flag));
	memset(path, 0, sizeof(path));
	int x, y;
	for (int i = 1; i <= n; i++) {
		g[i][i] = 1;
	}
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", &x, &y);//scanf比cin快很多,超时的话优先考虑这个
		g[x][y] = 1;
		g[y][x] = 1;
		path[x]++;
		path[y]++;
	}
	flag[1] = 1;
	if (!Even(path, n)) {//先判断度数,如果度数不符合要求直接输出0并结束,不需要再调用DFS/BFS,更节省时间
		cout << "0";
		return 0;
	}
	DFS(1, n);
	if (Count == n) {//上面已经判断过度数了,这里只要判断有没有把所有节点都遍历过就行了
		cout << "1";
	}
	else {
		cout << "0";
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_41478705/article/details/80338784
7-3
今日推荐