欧拉回路
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17430 Accepted Submission(s): 6723
Problem Description
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结
束。
束。
Output
每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
Sample Input
3 31 21 32 33 21 22 30
Sample Output
10
Author
ZJU
Source
解题思路:这题考的是一道裸的欧拉回路,那我们首先来讲讲什么是欧拉回路。
欧拉回路:就是你从一个点出发,经过所有的边一次,并且能回到起点,那么这个图就存在欧拉回路。
判定方法:
1、无向图:首先必须是个连通图,然后所有点的度数必须是偶数。
2、有向图:首先还得是个连通图,然后,所有点的
入度等于出度
。
然后判定无向图是否为连通图我们可以dfs,或者运用并查集解决,度数的判断在输入时就可以解决
AC代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<math.h> #include<stdlib.h> #include<queue> #include<map> #include<set> #define bug printf("*********\n"); #define mem0(a) memset(a, 0, sizeof(a)); #define mem1(a) memset(a, -1, sizeof(a)); #define in1(a) scanf("%d" ,&a); #define in2(a, b) scanf("%d%d", &a, &b); #define out1(a) printf("%d\n", a); #define out2(a, b) printf("%d %d\n", a, b); using namespace std; typedef long long LL; typedef pair<int, int> par; const int mod = 1e9+7; const int INF = 1e9+7; const int N = 1000010; const double pi = 3.1415926; int n, m, head[1001], cnt, vis[1001], du[1001]; struct node { int to; int next; }e[1000010]; void add(int u, int v) { e[cnt].to = v; e[cnt].next = head[u]; head[u] = cnt ++; } void dfs(int k) //连通图判定(无向O(n)) { for(int i = head[k]; i != -1; i = e[i].next) { int en = e[i].to; if(!vis[en]) { vis[en] = 1; dfs(en); } } } void init() { mem0(vis); mem1(head); mem0(du); cnt = 0; } int main() { int x, y; while(~scanf("%d", &n)) { if(!n) break; in1(m); init(); int flag = 0; for(int i = 0; i < m; i ++) { in2(x, y); du[x] ++; //度数计算 du[y] ++; add(x, y); add(y, x); //此题为无向图 } dfs(1); for(int i = 1; i <= n; i ++) { if(du[i]&1 || !vis[i]) flag = 1; } if(flag) printf("0\n"); else printf("1\n"); } return 0; }