博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NYOJ-42 一笔画问题
阅读量:5286 次
发布时间:2019-06-14

本文共 3668 字,大约阅读时间需要 12 分钟。

这个题可以有两种方式来解决, 一个是搜索来解决,另一个是用并查集,后者较前者来说要更快点

整个题的思路就是先判断整个图是否连通,然后再判断是否为欧拉图,即图中奇度顶点的个数是否为0或者2, 如果是0或者2的话就是欧拉图,就可以一笔画,所以,用搜索是来判断这个图是否连通,并查集也是,下面是代码的实现:

方法一(搜索):

1 #include
2 #include
3 #include
4 using namespace std; 5 6 int n, q; 7 int a[1010][1010]; 8 int vis[1010]; 9 int degree[1010];10 void dfs(int cur)11 {12 vis[cur] = 1;//如果能过去,就说明连通,标记为已经走过 13 for(int i = 1; i <= n; i++)14 {15 if(vis[i] == 0 && a[cur][i])16 {17 dfs(i);18 }19 }20 }21 int main()22 {23 int N;24 scanf("%d", &N);25 while(N--)26 {27 28 bool flag = true;29 scanf("%d %d", &n, &q);30 memset(a, 0, sizeof(a));31 memset(vis, 0, sizeof(vis));32 memset(degree, 0, sizeof(degree));33 int t1, t2;34 for(int i = 1; i <= q; i++)35 {36 scanf("%d %d", &t1, &t2);37 a[t1][t2] = 1;38 a[t2][t1] = 1;39 ++degree[t1];//统计节点的度数 40 ++degree[t2];41 }42 dfs(1);43 for(int i = 1; i <= n; i++)44 {45 if(vis[i] == 0)//如果图不连通 46 {47 flag = false;48 break;49 } 50 }51 int cnt = 0;52 if(flag)53 {54 for(int i = 1; i <= n; i++)55 {56 if(degree[i] % 2 == 1)57 cnt++;//统计奇度顶点的个数 58 }59 if(cnt != 0 && cnt != 2)60 flag = false;61 }62 if(flag)63 printf("Yes\n");64 else65 printf("No\n");66 67 68 }69 return 0;70 }71

方法二(并查集):

1 #include 
2 #include
3 #include
4 5 const int N = 1010; 6 int father[N], rank[N]; 7 int degree[N]; 8 9 int find(int n)10 {11 if (n != father[n])12 father[n] = find(father[n]);//路径压缩 13 return father[n];14 }15 //合并函数 16 void unin(int x, int y)17 {18 int n = find(x);19 int m = find(y);20 if(n != m)21 {22 //rank用来保存当前点有多少个孩子了,始终孩子少的归顺孩子多的,合并根节点 23 if (rank[n] > rank[m])24 {25 father[m] = n;26 rank[n]++;27 }28 else29 {30 father[n] = m;31 rank[m]++;32 }33 34 } 35 }36 int main()37 {38 int N;39 scanf("%d", &N);40 while(N--)41 {42 int p, q;43 scanf("%d %d", &p, &q);44 for(int i = 1; i <= p; i++)45 father[i] = i;//初始化每个节点的父亲为他本身 46 memset(rank, 0, sizeof(rank));//清零 47 memset(degree, 0, sizeof(degree));//统计每个节点的度, 48 int a, b;49 for(int i = 0; i < q; i++)50 {51 scanf("%d %d", &a, &b);52 unin(a, b);53 ++degree[a];54 ++degree[b];55 }56 bool flag = true;57 int t = father[1];//判断是否连通分量是否为1 58 for(int i = 2; i <= p; i++)59 {60 if (t != father[i])61 {62 flag = false;63 break;64 }65 }66 67 if(flag)68 {69 int cnt = 0;70 for(int i = 1; i <= q; i++)71 {72 if(degree[i] % 2 == 1)//统计奇度定点的个数 73 cnt++; 74 }75 if(cnt != 0 && cnt != 2)76 flag = false;77 }78 if(flag)79 printf("Yes\n");80 else81 printf("No\n");82 }83 return 0;84 }

 

转载于:https://www.cnblogs.com/Howe-Young/p/4082786.html

你可能感兴趣的文章
INSERT IGNORE INTO / REPLACE INTO
查看>>
Python数据类型-布尔/数字/字符串/列表/元组/字典/集合
查看>>
【刷题】SPOJ 705 SUBST1 - New Distinct Substrings
查看>>
IEEE 754浮点数表示标准
查看>>
declare 结构用来设定一段代码的执行指令
查看>>
图解算法读书笔记
查看>>
调试学习笔记
查看>>
解开lambda最强作用的神秘面纱
查看>>
Java基础:Object类中的equals与hashCode方法
查看>>
C#拦截Http请求
查看>>
图片下载器
查看>>
找不到docker.socket解决方法
查看>>
Activity生命周期
查看>>
sql server和mysql中分别实现分页功能
查看>>
kafka server管理
查看>>
系统设计与分析(六)
查看>>
Java IO-1 File类
查看>>
HW5.29
查看>>
Linux查看物理CPU个数,核数,逻辑CPU个数;内存信息
查看>>
sqlserver查询效率
查看>>