思路
首先欧拉回路是一个连通图,这个可以用并查集的模板来写,下面详尽的写了并查集的一个模板,具体关于并查集的知识我就不叙述了。
然后还要满足所有顶点的度为偶数,这个因为已经给出了各条边,很容易求出来度数
其中需要注意以下几点:
- 自环不用算,因为去掉自环也不会产生影响,但是加上自环的话会让度数计算产生问题。
- 孤立点不用算,也就是度为 0 的点,孤立点首先不会对欧拉回路产生影响,但是却会增加连通分支数量。
- 代码尽管很长,但是前面一半都是一个并查集模板类,main 函数中的代码前面一半也只是做了一个初始化的工作,后面一半就是判断是否连通分量为 1 以及是否度均为偶数。
#include<iostream>
#include<vector>
#include<numeric>
using namespace std;
class UF {
public:
vector<int> fa;
vector<int> sz;
int comp_cnt; // 连通分量数目
int n;
public:
UF(int _n) : n(_n), comp_cnt(_n), fa(_n), sz(_n, 1){
iota(fa.begin(), fa.end(), 0);
}
int findFa(int x){
return x == fa[x] ? x : fa[x] = findFa(fa[x]);
}
void unite(int x, int y){
x = findFa(x);
y = findFa(y);
if(x == y) return;
if(sz[x] < sz[y]) swap(x, y);
fa[y] = x;
sz[x] += sz[y];
comp_cnt --;
}
bool connected(int x, int y) {
x = findFa(x);
y = findFa(y);
return x == y;
}
};
int main(){
int N, M;
while(cin >> N && N){
cin >> M;
vector<int> degree(N, 0);
UF uf(N);
int x, y;
for(int i = 0; i < M; i ++){
cin >> x >> y;
// 去掉自环
if(x == y) continue;
uf.unite(x - 1, y - 1);
degree[x - 1] ++;
degree[y - 1] ++;
}
// 去掉孤立点也就是度为 0 的点
for(int d : degree)
if(d == 0) uf.comp_cnt --;
// 连通分量数目不为 1
if(uf.comp_cnt != 1) cout << 0 << endl;
else{
// 检查是否存在度为奇数的点
bool flag = true;
for(int d : degree)
if(d % 2){
flag = false;
cout << 0 << endl; break;
}
if(flag) cout << 1 << endl;
}
}
} 
京公网安备 11010502036488号