HDU1878 欧拉回路---(并查集+图论性质)
http://acm.hdu.edu.cn/showproblem.php?pid=1878
欧拉回路
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14317 Accepted Submission(s): 5423
Problem Description
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结
束。
束。
Output
每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
Sample Input
3 3
1 2
1 3
2 3
3 2
1 2
2 3
0
Sample Output
1
0
分析:
- 首先,判断是否构成连通图,用并查集实现
- 判断每个节点的度数是否为偶数(0除外)
#include "cstdio" const int N=1000+5; int father[N],degree[N]; void inti(int n) { for(int i=0;i<n;i++) { father[i]=i; degree[i]=0; } } int findFather(int x) { int a=x; while(father[x]!=x) x=father[x]; while(father[a]!=a) { int z=a; a=father[a]; father[z]=x; } return x; } void Union(int x,int y) { int faA=findFather(x); int faB=findFather(y); if(faA!=faB) father[faA]=faB; } int main() { int n,m; while(~scanf("%d",&n)&&n) { inti(n); scanf("%d",&m); int u,v; while(m--){ scanf("%d%d",&u,&v); degree[u-1]++;///求度数 degree[v-1]++; Union(u-1,v-1); } int cnt1=0,cnt2=0; for(int i=0;i<n;i++) { if(father[i]==i)///连通图 cnt1++; if(degree[i]==0||degree[i]%2!=0)///所有节点度数为偶数 cnt2++; } if(cnt1==1&&cnt2==0) printf("1\n"); else printf("0\n"); } return 0; }
如果不去做,永远不可能!