NYOJ-42 一笔画问题
2014-11-08 10:19
274 查看
这个题可以有两种方式来解决, 一个是搜索来解决,另一个是用并查集,后者较前者来说要更快点
整个题的思路就是先判断整个图是否连通,然后再判断是否为欧拉图,即图中奇度顶点的个数是否为0或者2, 如果是0或者2的话就是欧拉图,就可以一笔画,所以,用搜索是来判断这个图是否连通,并查集也是,下面是代码的实现:
方法一(搜索):
方法二(并查集):
整个题的思路就是先判断整个图是否连通,然后再判断是否为欧拉图,即图中奇度顶点的个数是否为0或者2, 如果是0或者2的话就是欧拉图,就可以一笔画,所以,用搜索是来判断这个图是否连通,并查集也是,下面是代码的实现:
方法一(搜索):
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n, q; int a[1010][1010]; int vis[1010]; int degree[1010]; void dfs(int cur) { vis[cur] = 1;//如果能过去,就说明连通,标记为已经走过 for(int i = 1; i <= n; i++) { if(vis[i] == 0 && a[cur][i]) { dfs(i); } } } int main() { int N; scanf("%d", &N); while(N--) { bool flag = true; scanf("%d %d", &n, &q); memset(a, 0, sizeof(a)); memset(vis, 0, sizeof(vis)); memset(degree, 0, sizeof(degree)); int t1, t2; for(int i = 1; i <= q; i++) { scanf("%d %d", &t1, &t2); a[t1][t2] = 1; a[t2][t1] = 1; ++degree[t1];//统计节点的度数 ++degree[t2]; } dfs(1); for(int i = 1; i <= n; i++) { if(vis[i] == 0)//如果图不连通 { flag = false; break; } } int cnt = 0; if(flag) { for(int i = 1; i <= n; i++) { if(degree[i] % 2 == 1) cnt++;//统计奇度顶点的个数 } if(cnt != 0 && cnt != 2) flag = false; } if(flag) printf("Yes\n"); else printf("No\n"); } return 0; }
方法二(并查集):
#include <stdio.h> #include <string.h> #include <stdlib.h> const int N = 1010; int father , rank ; int degree ; int find(int n) { if (n != father ) father = find(father );//路径压缩 return father ; } //合并函数 void unin(int x, int y) { int n = find(x); int m = find(y); if(n != m) { //rank用来保存当前点有多少个孩子了,始终孩子少的归顺孩子多的,合并根节点 if (rank > rank[m]) { father[m] = n; rank ++; } else { father = m; rank[m]++; } } } int main() { int N; scanf("%d", &N); while(N--) { int p, q; scanf("%d %d", &p, &q); for(int i = 1; i <= p; i++) father[i] = i;//初始化每个节点的父亲为他本身 memset(rank, 0, sizeof(rank));//清零 memset(degree, 0, sizeof(degree));//统计每个节点的度, int a, b; for(int i = 0; i < q; i++) { scanf("%d %d", &a, &b); unin(a, b); ++degree[a]; ++degree[b]; } bool flag = true; int t = father[1];//判断是否连通分量是否为1 for(int i = 2; i <= p; i++) { if (t != father[i]) { flag = false; break; } } if(flag) { int cnt = 0; for(int i = 1; i <= q; i++) { if(degree[i] % 2 == 1)//统计奇度定点的个数 cnt++; } if(cnt != 0 && cnt != 2) flag = false; } if(flag) printf("Yes\n"); else printf("No\n"); } return 0; }
相关文章推荐
- NYOJ-42 一笔画问题
- nyoj_42 一笔画问题
- NYOJ42 一笔画问题 欧拉回路判定+前向星
- NYOJ-42 一笔画问题(图论,深搜)
- NYOJ42-一笔画问题
- NYOJ 42 一笔画问题
- nyoj,42,一笔画问题
- NYOJ 42-一笔画问题:欧拉路径
- nyoj 42-一笔画问题
- NYOJ 42 一笔画问题 http://acm.nyist.net/JudgeOnline/problem.php?pid=42
- NYOJ 42 一笔画问题
- NYOJ42 一笔画问题
- NYOJ42 一笔画问题
- 欧拉路/回路_并查集 NYOJ 42 一笔画问题
- NYOJ 42 一笔画问题
- NYOJ-42 一笔画问题
- NYOJ42 一笔画问题
- NYOJ42-一笔画问题
- NYOJ 题目42 一笔画问题(欧拉路,图的连通性)
- Nyoj 42 一笔画问题