一笔画问题
时间限制:
3000 ms | 内存限制:65535 KB
难度:
4
-
描述
-
zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。
规定,所有的边都只能画一次,不能重复画。
-
输入
-
第一行只有一个正整数N(N<=10)表示测试数据的组数。
每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<=2000),分别表示这个画中有多少个顶点和多少条连线。(点的编号从1到P)
随后的Q行,每行有两个正整数A,B(0<A,B<P),表示编号为A和B的两点之间有连线。
输出
-
如果存在符合条件的连线,则输出"Yes",
如果不存在符合条件的连线,输出"No"。
样例输入
-
2 4 3 1 2 1 3 1 4 4 5 1 2 2 3 1 3 1 4 3 4
样例输出
-
No Yes
来源
- [张云聪]原创 上传者
- 张云聪
- 解题:欧拉回路的判断:需要完成两项任务:首先是判断图的连通性,必须要是连通的!然后,对于无向图,如果至多只有两个奇点,则一定存在欧拉回路,即可以一笔画!
-
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <vector> 6 #include <climits> 7 #include <algorithm> 8 #include <cmath> 9 #define LL long long 10 using namespace std; 11 vector<int>e[1010]; 12 int deg[1010]; 13 bool vis[1010]; 14 void dfs(int u) { 15 vis[u] = true; 16 for(int i = 0; i < e[u].size(); i++) { 17 if(!vis[e[u][i]]) { 18 dfs(e[u][i]); 19 } 20 } 21 } 22 int main() { 23 int kase,p,q,i,u,v,temp; 24 bool flag; 25 scanf("%d",&kase); 26 while(kase--) { 27 scanf("%d %d",&p,&q); 28 memset(deg,0,sizeof(deg)); 29 memset(vis,false,sizeof(vis)); 30 for(i = 0; i < 1010; i++) 31 e[i].clear(); 32 for(i = 0; i < q; i++) { 33 scanf("%d %d",&u,&v); 34 e[u].push_back(v); 35 e[v].push_back(u); 36 deg[u]++; 37 deg[v]++; 38 } 39 dfs(1); 40 flag = true; 41 for(i = 1; i <= p; i++) 42 if(!vis[i]) { 43 flag = false; 44 break; 45 } 46 if(flag) { 47 for(temp = 0,i = 1; i <= p; i++) { 48 if(deg[i]&1) { 49 temp++; 50 if(temp > 2) break; 51 } 52 } 53 } 54 if(!flag || temp > 2) puts("No"); 55 else puts("Yes"); 56 } 57 return 0; 58 }