http://acm.nyist.net/JudgeOnline/problem.php?pid=42
描述
zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。
规定,所有的边都只能画一次,不能重复画。
先用并查集判断是否连通,然后判断是否符合一笔画的条件
/*
* 一笔画 即线路不能中断,不能画重复线路
* 能否一笔画成,关键在于判别奇点、偶点的个数。
* ::只有偶点,可以一笔画,并且可以以任意一点作为起点
* ::只有两个奇点,可以一笔画,但必须以这两个奇点分别作为起点和终点。
* ::奇点超过两个,则不能一笔画。
* 对于一些比较复杂的路线问题,可以先转化为简单的几何图形,然后根据判定是否能一笔画的方法进行解答。
* 如果有限连通图 G 有 2k 个奇顶点,那么它可以用 k 笔画成,并且至少要用 k 笔画成[2]。
*/
import java.util.*;
import java.io.*;
public class Main {
private int N,v,e;
private int[] f;
private int[] num;
private int isCon;
static Scanner sc = new Scanner(new BufferedInputStream(System.in));
void init()
{
for(int i=1;i<=v;i++)
{
f[i]=i;
num[i]=1;
}
}
int findSet(int i)
{
if(f[i]!=i)
f[i]=findSet(f[i]);
return f[i];
}
void unionSet(int x,int y)
{
isCon++;
if(num[x]>num[y])
{
f[y]=x;
num[x]+=num[y];
}
else
{
f[x]=y;
num[y]+=num[x];
}
}
void start()
{
N=sc.nextInt();
while(N--!=0)
{
v=sc.nextInt();
e=sc.nextInt();
isCon=0;
int[] map=new int[v+1];
f=new int[v+1];
num=new int[v+1];
init();
for(int i=0;i<e;i++)
{
int m=sc.nextInt(),n=sc.nextInt();
map[m]++;
map[n]++;
int x=findSet(m),y=findSet(n);
if(x!=y)
unionSet(x,y);
}
int degree=0;
for(int i=1;i<=v;i++)
{
if((map[i]&1)==1)
degree++;
}
if(isCon!=v-1||degree!=0&°ree!=2)//先判断是否是连通图,然后判断是否符合一笔画的条件
System.out.println("No");
else
System.out.println("Yes");
}
}
public static void main(String[] args) {
new Main().start();
}
}