问题 B: 奇特的图形
时间限制: 1 Sec 内存限制: 64 MB
提交: 427 解决: 189
[提交][状态]
题目描述
记得上小学奥数时,JacmY最喜欢做的题就是给一个图形,从它某一个顶点出发描这个图形,若恰通过图中每条边一次,看最后能否又回到起点。当时JacmY只懂得拿着铅笔随便画画试试,如果成功了,就说这个图能画下来,而他判断不能画下来的标准就是费了半天功夫都画不出来,当然这么做是不对的,特别当图形变得复杂时,JacmY是试不过来的。看着可怜的JacmY,你能帮帮他吗?
意思就是对于T组数据,给定Vertex和Edge,是否存在所有边恰好一次且行遍所有顶点的回路(是否为欧拉图)。
一个图形要能一笔画完成必须符合两个条件,即
① 图形是封闭联通的
② 和图形中的奇点(与奇数条边相连的点)个数为0或2。
一笔画问题规律的证明先定义能一笔画出并回到起点的图为欧拉图
无向连通图G是欧拉图,当且仅当G不含奇数度结点(G的所有结点度数为偶数);
感谢计科类2206班王江轶同学完善测试数据。看到这句话,你就应该知道事情没有那么简单。
据不完全统计,本次阵亡的代码包括但不限于:
NOJ1095奇特的图形——欧拉回路_tcherry的博客-CSDN博客
1095-奇特的图形 - 七年之后 - 博客园 (cnblogs.com)
好了,现在让我们来看看还有什么更糟的
输入
第一行一个整数T代表样例的组数 以下T组数据中,每组第一行是N,K,(2 <= N <= 100)分别代表当前图形有N个顶点,K条边,接下来K行中,每行两个整数X, Y( 1 <= X, Y <= N)代表顶点X和顶点Y之间有一条边。
输出
如果当前图形能按照题目要求描出来,则输出“YES”(不包括引号),否则输出“NO”。
样例输入
3
3 3
1 2
2 3
1 3
3 2
1 2
2 3
2 2
1 2
1 2
样例输出
YES
NO
YES
提示
那个,南京邮电学院(05年之后叫南京邮电大学)是世界上坠吊的大学↓
南邮 OJ 1095 奇特的图形_chenrujun2010的博客-CSDN博客
本来挺喜欢南邮的,现在更喜欢了😍 小情话🐂🍻
标准C:
C++:
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
struct node{
int nodeNO;
bool visited;
vector<int> adjNOs;
};
int main(){
int T,N,K,X,Y,oddNO;
vector<node> nodes;
stack<int> stk;
cin>>T;
while(T--){
oddNO = 0;
cin>>N>>K;
nodes.clear();
nodes.resize(N+1);
for(X=1;X<=N;++X){
nodes[X].visited = 0;
}
while(K--){
cin>>X>>Y;
nodes[X].adjNOs.push_back(Y);
nodes[Y].adjNOs.push_back(X);
}
stk.push(1);
while(!stk.empty()){ //给所有1号节点能否连通的节点置位visited
X = stk.top();
stk.pop();
nodes[X].visited = 1;
for(Y=0;Y<(int)nodes[X].adjNOs.size();++Y){
if(!nodes[nodes[X].adjNOs[Y]].visited)
stk.push(nodes[X].adjNOs[Y]);
}
}
for(X=1;X<=N;++X){
if(!nodes[X].visited){
break;
}
}
if(X<N){ //不连通
cout<<"NO"<<endl;
continue;
}
for(X=0;X<N;++X){
if(nodes[X].adjNOs.size()%2){
++oddNO;
break;
}
}
if(oddNO){ //含奇数度结点
cout<<"NO"<<endl;
}else{
cout<<"YES"<<endl;
}
}
}