zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。 规定,所有的边都只能画一次,不能重复画。 输入 第一行只有一个正整数N(N<=
2017-08-25 20:49
916 查看
欧拉定理 如果一个网络是连通的并且奇顶点的个数等于0或2,那么它可以一笔画出;否则它不可以一笔画出。
判断一笔画的方法:
①是连通的。一个图,如果图上任意二点总有线段连接着,就称为连通的。不是连通的就不能一笔画出。
②奇点个数是0或者是2。图上线段的端点可以分成二类,奇点和偶数。一个点,以它为端点的线段数是奇数就称为奇点,线段数是偶数就称为偶点。
一个图是否是一笔画就看奇点的个数,奇点个数是 0 或者 2,就是一笔画,否则就不是一笔画。
所以这个问题完全可以转化策略为:
第一步: 首先我们不管它三七二十几,先进行连通性的判断。
第二步:
(1)如果是连通的,我们来判断此图的度的奇点的个数是0或者是2 ,如果是,则说明这个是欧拉图,即可以一笔画出,反之则不能一笔画出
(2)如果是非连通的,这说明这个图很定不能一笔画出。
#include<iostream>
#include<cstring>
using namespace std;
int edge[2000][2000];
int degree[2000];
int vis[2000];
int e;
void dfs(int cur)
{
for(int i=1;i<=e;i++)
{
if(!vis[i]&&edge[cur][i])
{
vis[i]=1;
dfs(i);
}
}
}
bool judge()
{
dfs(1);
for(int i=1;i<=e;i++)
{if(!vis[i])
return false;
}
int count=0;
for(int i=1;i<=e;i++)
{if(degree[i]%2)
count++;
}
if(count==2||count==0)
return true;
else
return false;
}
int main()
{
int n;
cin>>n;
while(n--)
{memset(vis,0,sizeof(vis));
memset(degree,0,sizeof(degree));
memset(edge,0,sizeof(edge));
int m;
cin>>e>>m;
while(m--)
{
int a,b;
cin>>a>>b;
edge[a][b]=edge[b][a]=1;
degree[a]++;
degree[b]++;
}
if(judge())
cout<<"Yes\n"<<endl;
else
cout<<"No\n"<<endl;
}
return 0;
}
判断一笔画的方法:
①是连通的。一个图,如果图上任意二点总有线段连接着,就称为连通的。不是连通的就不能一笔画出。
②奇点个数是0或者是2。图上线段的端点可以分成二类,奇点和偶数。一个点,以它为端点的线段数是奇数就称为奇点,线段数是偶数就称为偶点。
一个图是否是一笔画就看奇点的个数,奇点个数是 0 或者 2,就是一笔画,否则就不是一笔画。
所以这个问题完全可以转化策略为:
第一步: 首先我们不管它三七二十几,先进行连通性的判断。
第二步:
(1)如果是连通的,我们来判断此图的度的奇点的个数是0或者是2 ,如果是,则说明这个是欧拉图,即可以一笔画出,反之则不能一笔画出
(2)如果是非连通的,这说明这个图很定不能一笔画出。
#include<iostream>
#include<cstring>
using namespace std;
int edge[2000][2000];
int degree[2000];
int vis[2000];
int e;
void dfs(int cur)
{
for(int i=1;i<=e;i++)
{
if(!vis[i]&&edge[cur][i])
{
vis[i]=1;
dfs(i);
}
}
}
bool judge()
{
dfs(1);
for(int i=1;i<=e;i++)
{if(!vis[i])
return false;
}
int count=0;
for(int i=1;i<=e;i++)
{if(degree[i]%2)
count++;
}
if(count==2||count==0)
return true;
else
return false;
}
int main()
{
int n;
cin>>n;
while(n--)
{memset(vis,0,sizeof(vis));
memset(degree,0,sizeof(degree));
memset(edge,0,sizeof(edge));
int m;
cin>>e>>m;
while(m--)
{
int a,b;
cin>>a>>b;
edge[a][b]=edge[b][a]=1;
degree[a]++;
degree[b]++;
}
if(judge())
cout<<"Yes\n"<<endl;
else
cout<<"No\n"<<endl;
}
return 0;
}
相关文章推荐
- 输入两个正整数m和n(m<n),求m到n之间(包括m和n)所有素数的和,要求定义并调用函数isprime(x)来判断x是否为素数(素数是除1以外只能被自身整除的自然数)。
- (1)任务描述 编写一个程序:输入一个身份证号,判断该号码对应的人是否是18至25岁女孩,是则输出”yes”,否则输出”no” (2)功能要求 ①输入一行给出正整数N(<= 100)是输入的身份证号码
- 编写程序,判断用户输入的数字是否完全数.所谓“完全数”是指整数n的所有因子(不包括n)之和等于n自身。例如28的因子为1、2、4、7、14,而28=1+2+4+7+14,因此28是“完全数”。
- /*编写程序,其中自定义一函数,用来判断一个整数是否为素数,主函数输入一个数,输出是否为素数*/
- 转: 闰年判断 写一个程序,能够判断从键盘上输入的年份是否是一个闰年
- P53.37(设计一个程序,从键盘输入一个正整数M,判断该正整数是否左右对称,若对称,则输出yes,否则输出no。)
- 输入一个卡号判断是否合法。其中卡号长度为16-19位,只能是数字。满足:
- 给出N个正整数,其中只有一个数出现了奇数次,其余的数都出现偶数次。求那个出现了奇数次的数。1<=N<=1000,N肯定是奇数。所有出现的整数都不超过1000。
- c程序:编写程序,其中自定义一函数,用来判断一个整数是否为素数,主函数输入一个数,输出是否为素数
- 任意输入20个正整数,找出其中的素数,并将这些素数按由小到大排序。要求:判断一个数是否为素数用函数实现:排序用函数实现
- P51.19(请输入一个正整数n,判断其中各位数字是否奇偶交替出现。)
- ACM457现在给出了一个只包含大小写字母的字符串,不含空格和换行,要求把其中的大写换成小写,小写换成大写,然后输出互换后的字符串。输入 第一行只有一个整数m(m<=10),表示测试数据组数。
- 编写一段程序,从标准输入读取string对象的序列直到连续出现两个相同的单词或者所有单词都读完为止。使用while循环一次读取一个单词,当一个单词连续出现两次是使用break语句终止循环。输出连续重复出现的单词,或者输出一个消息说明没有人任何单词是重复出现的。
- 闰年判断 写一个程序,能够判断从键盘上输入的年份是否是一个闰年
- 写一个彩票程序 30选7 随机(1~30中间)生成7个随机数,注意不能重复然后输入7个数,对比7个数是否与随机数有相同的,如果有显示“中了几个号” 如果中了7个号,显示一等奖 如果中了6个号,显示二
- C语言实现的一个程序只能运行一次,不能重复运行
- 输入包括两行,第一行是一个正整数N(N<=1000000),表示理工大共N个美女。第二行有N个正整数分别表示N位美女的身高,每个正整数的值不会超过10^9。 (输入数据之间会用空格隔开)
- 判断正整数m是否为完全数(如果一个正整数m的所有小于m的因子(包括1)加起来正好等于m本身,那么这个数就称为完全数)
- 输入正整数n,按从小到大的顺序输出所有形如abcde/fghij=n的表达式,其中a~j恰好为数字0~9的一个排列(可以有前导0),2<=n<=79
- 输入包括两行,第一行是一个正整数N(N<=1000000),表示理工大共N个美女。第二行有N个正整数分别表示N位美女的身高,每个正整数的值不会超过10^9。 (输入数据之间会用空格隔开)