一笔画问题
- 描述
-
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
先来介绍一下关于欧拉回路判定定理的知识点
G 为连通图,并且G 仅有两个奇度结点(度数为奇数的顶点)或者无奇度结点。
推论5.1:
1) 当G 是仅有两个奇度结点的连通图时,G 的欧拉通路必以此两个结点为端点。
2) 当G 是无奇度结点的连通图时,G 必有欧拉回路。
3) G 为欧拉图(存在欧拉回路)的充分必要条件是G 为无奇度结点的连通图。
定理5.2
有向图D 存在欧拉通路的充要条件是:
D 为有向图,D 的基图连通,并且所有顶点的出度与入度都相等;或者除两个顶点外,其余
顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度
与入度之差为-1。
推论5.2:
1) 当D 除出、入度之差为1,-1 的两个顶点之外,其余顶点的出度与入度都相等时,D 的
有向欧拉通路必以出、入度之差为1 的顶点作为始点,以出、入度之差为-1 的顶点作为
终点。
2) 当D 的所有顶点的出、入度都相等时,D 中存在有向欧拉回路。
3) 有向图D 为有向欧拉图的充分必要条件是D 的基图为连通图,并且所有顶点的出、入度
都相等。
package bfs;
import java.util.Arrays;
import java.util.Scanner;
/**
*
*/
public class Main42 {
static int p,q;
static int a[][]=new int[1000+10][1000+10];
static int pd[]=new int[1000+10];
static boolean vis[]=new boolean[1000+10];
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int t=scanner.nextInt();
while (t-->0){
p=scanner.nextInt();
q=scanner.nextInt();
init();
Arrays.fill(pd,0);
for (int i=0;i<q;i++){
int u=scanner.nextInt();
int v=scanner.nextInt();
a[u][v]=1;
a[v][u]=1;
pd[u]++;
pd[v]++;
}
//判断是否是连通图
Arrays.fill(vis,false);
dfs(1);
boolean flag=true;
for (int i=1;i<=p;i++){
if (!vis[i]){
flag=false;
break;
}
}
int sum=0;
for (int i=1;i<=p;i++){
if (pd[i]%2==1){
sum++;
}
}
if(sum!=0&&sum!=2){
flag = false;
}
if(flag)
System.out.println("Yes");
else System.out.println("No");
}
}
private static void dfs(int s) {
vis[s]=true;
for (int i=0;i<=p;i++){
if (i!=s&&a[s][i]==1&&!vis[i]){
dfs(i);
}
}
}
private static void init() {
for (int i=0;i<1000+10;i++){
for (int j=0;j<1000+10;j++){
a[i][j]=0;
}
}
}
}