7-3哥尼斯堡的“七桥问题”(25 分)
如果一个回路是欧拉路径,则称为欧拉回路。
具有欧拉回路的图称为欧拉图(简称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
代码:
小知识(ゝω・)
欧拉回路:如果图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; }