小丁最近迷恋上一个游戏,传说中的“一笔画”游戏。
那么什么是一笔画?如下图,顾名思义就是一笔可以完成的图。一笔画最基本的要求是在画图的过程中,笔不能离开纸,且笔所画过的线不能重复,最后画完所有的线便算完成。
虽然小丁喜欢玩这个游戏,但有时候花费半天也找不到答案。小丁听说写一个计算机程序便能判断是否可以一笔画图,所以他希望善良可爱的你来帮帮他的忙。快来帮帮弱小,可怜,又无助的小丁
输入格式:
给出图中的节点数N(1<=N<=1000,编号1-N)和边数M;随后M行给出存在边的两个节点的编号。输出格式: 能够一笔画的图输出Y,否则输出N。
输入样例1:
3 2 1 2 2 3
输出样例1:
Y
分析:题意很明确,我们首先建图,既然需要满足一笔画,那么图必须联通,我们可以dfs跑一遍。但这还不够,在一笔画的过程中,我们发现,假设a有邻接点b1,b2,b3,当我们从a到b1时,不可能再从a到b2或者b3,也就是任意一个点只能通过自己的一个邻接点,这用break即可实现。
还有一个问题:就是每次从哪个点开始画,一开始我是每次默认从1开始画,虽然题过了,但是发现了 错误的情况。于是我们可以循环n次,每次从第i(1<=i<=n)开始画,遇到有解情况即输出’Y’。
AC代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int N=1e5+5;
vector<int>v[N];
int n,m,vis[N];
void dfs(int x) {
for(int i=0; i<v[x].size(); i++) {
if(!vis[v[x][i]]) {
vis[v[x][i]]=1;
dfs(v[x][i]);
break;//只能经过一个邻接点
}
}
}
int main() {
cin>>n>>m;
while(m--) {
int a,b;
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
//从1到n开始dfs,并标记为 “已经访问”
for(int i=1; i<=n; i++) {
vis[i]=1;
dfs(i);
int j;
for(j=1; j<=n; j++)
if(!vis[j])
break;
//所有点都已经访问,那么说明可以“一笔画”
if(j>n) {
cout<<"Y";
return 0;
}
memset(vis,0,sizeof vis);
}
cout<<"N";
return 0;
}