一笔画问题

来源:互联网 发布:Js 线程 编辑:程序博客网 时间:2024/04/29 05:01
/*描述zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。规定,所有的边都只能画一次,不能重复画。 输入第一行只有一个正整数N(N<=10)表示测试数据的组数。每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<=2000),分别表示这个画中有多少个顶点和多少条连线。(点的编号从1到P)随后的Q行,每行有两个正整数A,B(0<A,B<P),表示编号为A和B的两点之间有连线。输出如果存在符合条件的连线,则输出"Yes",如果不存在符合条件的连线,输出"No"。样例输入24 31 21 31 44 51 22 31 31 43 4样例输出NoYes一笔成画:就是说存在欧拉回路或者存在欧拉通路(涉及到离散数学),那么存在欧拉回路的条件:G是联通图且无奇度顶点!存在欧拉回路:G是连通图却恰好有两个奇度顶点!所以首先判断是否联通!再连通图的基础上,判断有没有奇度顶点,有几个!*///并查集 #include <stdio.h>#include <string.h>int pre[1005],s[1005];int find(int x){if(x!=pre[x])pre[x]=find(pre[x]);return pre[x];}void join(int x,int y){int fx,fy;fx=find(x);fy=find(y);if(fx!=fy)pre[fx]=fy;}int main(){int n,p,q;int a,b;scanf("%d",&n);int i,sum,sum_1;while(n--){sum=0;sum_1=0;memset(s,0,sizeof(s));scanf("%d%d",&p,&q);for(i=1;i<=p;i++)pre[i]=i;for(i=1;i<=q;i++){scanf("%d%d",&a,&b);s[a]++;s[b]++;join(a,b);}for(i=1;i<=p;i++){if(find(i)==i)sum++;if(s[i]%2!=0)sum_1++;}if(sum==1&&(sum_1==0||sum_1==2))printf("Yes\n");elseprintf("No\n");}return 0;}//深搜 #include <stdio.h>#include <string.h>int e[1005][1005],book[1005];int sum;int p,q;void dfs(int n){int i;book[n]=1;//把该点标记 for(i=1;i<=p;i++){if(e[n][i]!=0){if(!book[i])//进行下一点的搜索 dfs(i);}}}int main(){int n,i;int a,b;int number;int c[1005];scanf("%d",&n);while(n--){scanf("%d%d",&p,&q);sum=0;memset(e,0,sizeof(e));memset(book,0,sizeof(book));memset(c,0,sizeof(c));for(i=1;i<=q;i++){scanf("%d%d",&a,&b);e[a][b]=e[b][a]=1;c[a]++;c[b]++;}dfs(1); int flag=0;for(i=1;i<=p;i++)//判断是否连通 {if(book[i]==0){flag=1;break;}}if(flag){printf("No\n");}else{for(i=1;i<=p;i++){if(c[i]%2!=0)sum++;}if(sum==0||sum==2)printf("Yes\n");elseprintf("No\n");}}return 0;}

0 0
原创粉丝点击