7-4 一笔画 (25 分)
小丁最近迷恋上一个游戏,传说中的“一笔画”游戏。
那么什么是一笔画?如下图,顾名思义就是一笔可以完成的图。一笔画最基本的要求是在画图的过程中,笔不能离开纸,且笔所画过的线不能重复,最后画完所有的线便算完成。
虽然小丁喜欢玩这个游戏,但有时候花费半天也找不到答案。小丁听说写一个计算机程序便能判断是否可以一笔画图,所以他希望善良可爱的你来帮帮他的忙。
快来帮帮弱小,可怜,又无助的小丁。
输入格式:
给出图中的节点数N(1<=N<=1000,编号1-N)和边数M;随后M行给出存在边的两个节点的编号。
输出格式:
能够一笔画的图输出Y,否则输出N。
输入样例1:
3 2
1 2
2 3
输出样例1:
Y
输入样例2:
4 3
1 2
1 3
1 4
输出样例2:
N
从题目中看出,点可以多次遍历,但是边只能遍历一次,所以我们要存边,通过dfs能经过的边数来判断是否“一笔画”;
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e3+5;
int n,m,vis[maxn],cnt,ans,flag;
struct node{
int u,v;
}edge[maxn]; //边
void dfs(int st){
for(int i=0;i<cnt;++i){
if(flag) return;
if(!vis[i]&&edge[i].u==st){
vis[i]=1; ans++;
if(ans==cnt){//类似于全排列的判断
flag=1;
cout<<"Y"; return;
}
dfs(edge[i].v);
vis[i]=0; ans--;
}
}
}
int main(){
cin>>n>>m;
if(n==1){ //特判只有一个点的情况
cout<<"Y"; return 0;
}
for(int i=1,u,v;i<=m;++i){
cin>>u>>v; //建边
edge[cnt].u=u;
edge[cnt++].v=v;
}
for(int i=1;i<=n;++i){
dfs(i); //以每个点为起点搜索
}
if(!flag) cout<<"N";
return 0;
}
year!