题意:给出给你一个n和m,n是顶点的取值范围,范围是0~n-1,m是边的数量,然后判断这个图是否存在欧拉回路。
坑点:
1.n不是顶点的数量,而是顶点会出现在0~n-1这个范围!这个点wrong了无数发。
2.m = 0时,要输出Not Possible。无情wrong一发。
AC代码:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 205;
struct UFset{
int p[maxn];
int Find(int x){return p[x] >= 0 ? p[x] = Find(p[x]) : x;}
void Union(int r1, int r2){
r1 = Find(r1);
r2 = Find(r2);
int t = p[r1] + p[r2];
if(p[r1] < p[r2]){
p[r2] = r1;
p[r1] = t;
}
else{
p[r1] = r2;
p[r2] = t;
}
}
void Clear(){
for(int i = 0; i < maxn; i++)
p[i] = -1;
}
};
int n,m;
UFset t;
int degree[maxn];
bool euler(){
if(m == 0) return false;
for(int i = 0; i < n; i++){
if(degree[i] == 0) continue;
if(degree[i] & 1) return false;
}
//判连通
int first = -1;
for(int i = first+1; i < n; i++){
if(degree[i] == 0) continue;
if(first == -1) first = i;
if(t.Find(first) != t.Find(i)) return false;
}
return true;
}
int main(){
while(scanf("%d%d",&n,&m) == 2){
t.Clear();
int u,v;
for(int i = 0; i < n; i++) {
degree[i] = 0;
}
for(int i = 0; i < m; i++){
scanf("%d%d",&u,&v);
degree[u]++; degree[v]++;
if(t.Find(u) != t.Find(v))
t.Union(u,v);
}
puts(euler()?"Possible":"Not Possible");
}
return 0;
}