【NYOJ42】一笔画问题

一笔画问题

时间限制:3000 ms  |  内存限制:65535 KB
难度:4

Position:http://acm.nyist.net/JudgeOnline/problem.php?pid=42

Description

zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。

规定,所有的边都只能画一次,不能重复画。

Input

第一行只有一个正整数N(N<=10)表示测试数据的组数。
每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<=2000),分别表示这个画中有多少个顶点和多少条连线。(点的编号从1到P)
随后的Q行,每行有两个正整数A,B(0<A,B<P),表示编号为A和B的两点之间有连线。

Output

如果存在符合条件的连线,则输出"Yes",
如果不存在符合条件的连线,输出"No"。
input
2 
4 3
1 2
1 3
1 4
4 5
1 2
2 3
1 3
1 4
3 4
output
No Yes

Solution

欧拉回路知识,(不懂请点击链接),无向连通图G含有欧拉通路(即一笔画),当且仅当G有零个或两个奇数度的结点;

Code

 1 // <42.cpp> - Wed Oct  5 11:56:45 2016
 2 // This file is made by YJinpeng,created by XuYike's black technology automatically.
 3 // Copyright (C) 2016 ChangJun High School, Inc.
 4 // I don't know what this program is.
 5 
 6 #include <iostream>
 7 #include <vector>
 8 #include <algorithm>
 9 #include <cstring>
10 #include <cstdio>
11 #include <cstdlib>
12 #include <cmath>
13 #include <set>
14 #pragma GCC push_options
15 #pragma GCC optimize ("O2")
16 #define MOD 1000000007
17 #define INF 1e9
18 #define IN inline
19 #define RG register
20 using namespace std;
21 typedef long long LL;
22 typedef long double LB;
23 const int MAXN=100010;
24 const int MAXM=100010;
25 inline int max(int &x,int &y) {return x>y?x:y;}
26 inline int min(int &x,int &y) {return x<y?x:y;}
27 inline LL gi() {
28     register LL w=0,q=0;register char ch=getchar();
29     while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
30     if(ch=='-')q=1,ch=getchar();
31     while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
32     return q?-w:w;
33 }
34 struct Fleury{
35     static const int N=1010,M=N<<2;
36     int n,m;int f[N];set<int>s[N];
37     IN int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
38     IN bool pan_n(){
39         set<int>::iterator it;
40         for(int i=1;i<=n;i++)f[i]=i;
41         for(int i=1;i<=n;i++)
42             for(it=s[i].begin();it!=s[i].end();it++)
43                 if(find(i)!=find(*it))f[f[i]]=f[*it];
44         find(1);//this
45         int fa=f[1],k=0;
46         for(int i=1;i<=n;i++){
47             find(i);//this
48             if(f[i]!=fa)return 0;
49             if(s[i].size()&1)k++;
50         }
51         if(k==2)return 1;return 0;
52     }
53     IN void read(){
54         n=gi();m=gi();
55         for(int i=1;i<=n;i++)s[i].clear();
56         while(m--){
57             int u=gi(),v=gi();
58             s[u].insert(v);s[v].insert(u);
59         }
60         if(pan_n())printf("Yes
");else printf("No
");
61     }
62 }ou;
63 int main()
64 {
65     freopen("42.in","r",stdin);
66     freopen("42.out","w",stdout);
67     int T=gi();
68     while(T--)ou.read();
69     return 0;
70 }
原文地址:https://www.cnblogs.com/YJinpeng/p/5932139.html