ACM算法之 欧拉回路
2013-03-10 22:38
351 查看
题目描述:
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
输入:
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结束。
输出:
每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
样例输入:
样例输出:
什么是欧拉回路?
这个我起初以为很简单,就是一个环而已,所以每个顶点只要出现偶数次(至少是2次,不能是0次),就说明有环。
太简单了吧? 在九度OJ是可以过的,只能说明这个OJ太弱了。
换到HDU就不行了。因为没有考虑到 独立环 这种情况。题目要求是:每天边都要遍历,而且只能有一次。
所以,符合下面两点就行了:
1、可以用并查集,来检测是不是所有点都在一个集合里。
2、每个点 上的边是偶数。因为,如果 (1)这个点是起点,肯定有一条边出,一条边进,2条边。如果(2)这个点不是起点,肯定是有进必有出,即偶数!
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
输入:
测试输入包含若干测试用例。每个测试用例的第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
什么是欧拉回路?
这个我起初以为很简单,就是一个环而已,所以每个顶点只要出现偶数次(至少是2次,不能是0次),就说明有环。
#include <stdio.h> #include <string.h> int du[1000]; int main() { int n, m; int u, v; int i; while(scanf("%d", &n) && n != 0) { memset(du, 0, sizeof(du)); scanf("%d", &m); while(m--) { scanf("%d %d", &u, &v); du[u]++; du[v]++; } int flag = 1; for(i = 1; i <= n; i++) { if(du[i]&1){ flag = 0; break; } } printf("%d\n",flag); } return 0; }
太简单了吧? 在九度OJ是可以过的,只能说明这个OJ太弱了。
换到HDU就不行了。因为没有考虑到 独立环 这种情况。题目要求是:每天边都要遍历,而且只能有一次。
所以,符合下面两点就行了:
1、可以用并查集,来检测是不是所有点都在一个集合里。
2、每个点 上的边是偶数。因为,如果 (1)这个点是起点,肯定有一条边出,一条边进,2条边。如果(2)这个点不是起点,肯定是有进必有出,即偶数!
#include <stdio.h> int arr[1000]; int father[1000]; int rand_deep[1000]; int findSet(int x){ int px = x,i; while(px != father[px]) px = father[px]; //路径压缩,加快查找速度 while(x != px){ i = father[x]; father[x] = px; x = i; } return px; } void unionSet(int x,int y){ x = findSet(x); y = findSet(y); if(rand_deep[x] > rand_deep[y]) father[y] = x; else{ father[x] = y; if(rand_deep[x]==rand_deep[y])rand_deep[y]++; } } int main() { int N,M; while( scanf("%d",&N) != EOF && N){ scanf("%d",&M); int i; int flag = 1; for(i=1; i<=N; i++){ father[i] = i; rand_deep[i] = 0; arr[i] = 0; } for(i=0; i<M; i++){ int x,y; scanf("%d %d",&x, &y); arr[x] ++; arr[y] ++; unionSet(x , y); } int father; for(i=1; i<=N; i++){ if(i==1) father = findSet(1); else{ if(father!=findSet(i)){ flag = 0; break; } } if(arr[i] == 0 || arr[i]%2 != 0){ flag = 0; break; } } printf("%d\n",flag); } return 0; }
相关文章推荐
- ACM 题型算法分类
- 武汉科技大学ACM :1003: 零起点学算法78——牛牛
- 武汉科技大学ACM:1010: 零起点学算法89——母牛的故事
- 【ACM】基本算法分类|推荐学习资料…
- ACM必须掌握的算法
- acm算法有用吗?写给自己。
- Pku acm 3041 Asteroids 数据结构题目解题报告(十六)---- 匈牙利算法求二分图的最大匹配
- 借ACM一道题 关于算法优化的一点感想
- ACM算法学习状态-高级
- 杭电ACM1116——Play on Words~~欧拉路径与欧拉回路
- acm 常用算法
- ACM算法相关资料
- ACM - 算法篇,基础题目
- ACM中常用算法—-字符串
- Fleury(佛罗莱)算法求欧拉回路的学习
- ACM-ICPC 常用算法刷题网站整理
- ACM的算法分类
- ACM UVa 算法题100, 101, 103, 104, 112, 10405解法
- 算法竞赛入门经典:第六章 数据结构基础 6.14欧拉回路
- ACM 题型算法分类总结