-
题目描述:
-
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
-
输入:
-
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结束。
-
输出:
-
每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
-
样例输入:
-
3 3 1 2 1 3 2 3 3 2 1 2 2 3 0
-
样例输出:
-
1 0
/* 定理:如果G是连通图,则G是欧拉图当且仅当G的所有顶点都是偶顶点 证明(粗略)如下: 必要性:如果是欧拉图,有进有出,很容易就能判断G连通且所有顶点都是偶定点. 充分性:就是构造欧拉回路,去掉后再看剩下的部分是否是个欧拉图.. */ #include <cstdio> #include <string.h> #include <ctype.h> int tree[1001]; int deg[1001]; //从缓冲区读入int,注意如果后面需要读入char的时候. inline bool getint(int &x){ x = 0; int mute = 1; char c; while(!isdigit(c = getchar()) && c != '-') if(c == -1) return false; c == '-' ? mute = -1 : x = c - '0'; while(isdigit(c = getchar())) x = (x << 1) + (x << 3) + c - '0'; x *= mute; return true; } //并查集findroot. inline int find(int x){ if(tree[x] == -1) return x; else{ int tmp = find(tree[x]); tree[x] = tmp; return tmp; } } int main(){ int n, m, a, b, i, sum; bool yes; while(getint(n) && n){ getint(m); yes = true; memset(tree, -1, sizeof(tree)); memset(deg, 0, sizeof(deg)); for(i = 1; i <= m; i++){ getint(a); getint(b); deg[a]++; deg[b]++; a = find(a); b = find(b); if(a != b) tree[a] = b; } sum = 0; for(i = 1; i <= n; i++){ if(deg[i] % 2 != 0) yes = false; if(tree[i] == -1) sum++; } if(sum >= 2) yes = false; puts(yes ? "1" : "0"); } return 0; }