一笔画 (25 分)

小丁最近迷恋上一个游戏,传说中的“一笔画”游戏。

那么什么是一笔画?如下图,顾名思义就是一笔可以完成的图。一笔画最基本的要求是在画图的过程中,笔不能离开纸,且笔所画过的线不能重复,最后画完所有的线便算完成。
在这里插入图片描述
虽然小丁喜欢玩这个游戏,但有时候花费半天也找不到答案。小丁听说写一个计算机程序便能判断是否可以一笔画图,所以他希望善良可爱的你来帮帮他的忙。

快来帮帮弱小,可怜,又无助的小丁
输入格式:
给出图中的节点数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;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值