小知识(ゝω・)
欧拉回路:如果图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;
}