一笔画问题 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。 规定,所有的边都只能画一次,不能重复画。 输入 第一行只有一个正整数N(N<=10)表示测试数据的组数。 每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<=2000),分别表示这个画中有多少个顶点和多少条连线。(点的编号从1到P) 随后的Q行,每行有两个正整数A,B(0<A,B<P),表示编号为A和B的两点之间有连线。 输出 如果存在符合条件的连线,则输出"Yes", 如果不存在符合条件的连线,输出"No"。 样例输入 2 4 3 1 2 1 3 1 4 4 5 1 2 2 3 1 3 1 4 3 4 样例输出 No Yes
判断是不是一个欧拉图
1.是一个连通图
2.只有2个或者没有奇数结点
#include <iostream> #include <cstring> using namespace std; const int Max = 1001; int num[Max]; int f[Max]; int getf(int v) { if(f[v]==v) return v; else {f[v]= getf(f[v]); return f[v];} } int merg(int a, int b) { int t1 = getf(a); int t2 = getf(b); if(t1 != t2) { f[t2] = t1; return 1; } return 0; } int main() { int n; int vn,en; cin >> n; while(n--) { cin >> vn >> en; for(int i = 1; i <= vn;i++) f[i] = i; memset(num,0,sizeof(num)); int count = 0; int a,b; int sign = 0; for(int i = 0; i < en; i++) { cin >> a >> b; merg(a,b); //合并a,b结点 num[a]++; num[b]++; } for(int i =1; i < vn; i++) if(merg(i,i+1)) //不连通,退出循环 { sign = 1; cout << "No" << endl; break; } if(sign) continue; for(int i = 1; i <= vn; i++) if(num[i] % 2 == 1) count ++; if(count == 0 || count == 2) cout << "Yes" << endl; else cout << "No" << endl; } system("pause"); return 0; }