[牛客]浙江大学计算机考研复试题目 – 欧拉回路
- 2020 年 4 月 8 日
- 筆記
浙江大学考研复试题目 – 欧拉回路
题目描述
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
输入描述:
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结束。
输出描述:
每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
示例1
输入
[复制](javascript:void(0)?
3 3 1 2 1 3 2 3 3 2 1 2 2 3 0
输出
[复制](javascript:void(0)?
1 0
解题报告
判断欧拉回路的方法: 无向图存在欧拉回路的充要条件 一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。 有向图存在欧拉回路的充要条件 一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图。 1.连通判断 - 并查集/dfs/bfs 2.度数判断
tips
本题要求存在欧拉回路,并不是要求全部的点都连通,只需要连通的图构成欧拉回路即可。
#include <bits/stdc++.h> #define maxn 1010 using namespace std; int N,M; // int maps[maxn][maxn]; int father[maxn]; int du[maxn]; int findfather(int x) { return x==father[x]?x:findfather(father[x]); } bool combine(int x,int y) { int fx = findfather(x); int fy = findfather(y); if(fx == fy) return false; else { if(fx<fy) { father[y] = fx; } else { father[x] = fy; } } return true; } int counts() //并查集判断连通 { int ans = 0; for(int i=1;i<=N;i++) if(father[i] == i) ans++; return ans; } bool judgeDu(int n) { for(int i=1;i<=n;i++) { if(du[i]%2!=0) return false; } return true; } int main() { ios::sync_with_stdio(false); while(~scanf("%d",&N)&&N!=0) { if(N==0) break; scanf("%d",&M); for(int i=1;i<=N;i++) father[i] = i; memset(maps,0,sizeof(maps)); memset(du,0,sizeof(du)); int px,py; for(int j=0;j<M;j++) { scanf("%d %d",&px,&py); du[px]++; du[py]++; combine(px,py); } int onlypoint = 0; //度为 0 的就是孤立节点 for(int i=1;i<=N;i++) { if(du[i] == 0) { onlypoint++; } } if(counts()-onlypoint == 1 && judgeDu(N)){ printf("1n"); }else { printf("0n"); } } }