南邮 OJ 1095 奇特的图形

奇特的图形

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 179            测试通过 : 78 

比赛描述

记得上小学奥数时,JacmY最喜欢做的题就是给一个图形,从它某一个顶点出发描这个图形,若恰通过图中每条边一次,看最后能否又回到起点。当时JacmY只懂得拿着铅笔随便画画试试,如果成功了,就说这个图能画下来,而他判断不能画下来的标准就是费了半天功夫都画不出来,当然这么做是不对的,特别当图形变得复杂时,JacmY是试不过来的。看着可怜的JacmY,你能帮帮他吗?

输入

 第一行一个整数T代表样例的组数。

 以下T组数据中,每组第一行是NK(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

题目来源

Internet




//个图形要能一笔画完成必须符合两个条件,即图形是封闭联通的和图形中的
//奇点(与奇数条边相连的点)个数为0或2。
// 一笔画问题规律的证明先定义能一笔画出并回到起点的图为欧拉图
//无向连通图G是欧拉图,当且仅当G不含奇数度结点(G的所有结点度数为偶数);


#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;
		}
	}
}






你可能感兴趣的:(ACM,欧拉图,南邮OJ)