一笔画问题
时间限制: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
欧拉定理 : 如果一个网络是连通的并且奇顶点的个数等于0或2,那么它可以一笔画出;否则它不可以一笔画出。
所以这个题先用DFS搜索图是否连通,然后再判断奇结点个数就行了。import java.util.Scanner; public class 一笔画问题 { static boolean[] vis; static int[] degree; //记录一个结点的度 static int [][] map; static int n,m; //点数,边数 public static void main(String[] args) { Scanner sc =new Scanner(System.in); int tcase = sc.nextInt(); while(tcase-->0){ n = sc.nextInt(); m= sc.nextInt(); map = new int[n+1][n+1]; vis = new boolean [n+1]; degree = new int[n+1]; for(int i=1;i<=m;i++){ int x = sc.nextInt(); int y = sc.nextInt(); map[x][y] = map[y][x] =1; } dfs(1); boolean flag = true; for(int i=1;i<=n;i++){ if(!vis[i]){ flag = false; } } int count=0; for(int i=1;i<=n;i++){ if(degree[i]%2==1) count++; } if(count!=0&&count!=2){ flag = false; } if(flag) System.out.println("Yes"); else System.out.println("No"); } } //判断图是否连通 private static void dfs(int cur) { vis[cur] =true; for(int i=0;i<=n;i++){ if(map[cur][i]==1){ degree[cur]++; if(vis[i]==false) dfs(i); } } } }