您的位置:首页 > 其它

HPU1250: HH的米5 【并查集】+【欧拉图】

2014-12-21 23:06 183 查看

1250: HH的米5

Time Limit: 1 Sec  Memory Limit:
128 MB
Submit: 90  Solved: 25

[Submit][Status][Web
Board] [Edit]

Description

HH新买了一台手机小米5,他给自己的新手机设置了一个高端大气上档次的屏幕保护锁(其实就是一个9宫锁屏),保护锁有一个特点,就是需要一笔画下来才能解锁,HH就在想,如果给定N个点和M条边,那么该图是否可以通过一笔将该图画下来呢?他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。规定,所有的边都只能画一次,不能重复画。

Input

第一行只有一个正整数T(T<=10)表示测试数据的组数。每组测试数据的第一行有两个正整数N,M(N<=1000,M<=2000),分别表示这个画中有多少个顶点和多少条连线。(点的编号从1到N)随后的M行,每行有两个正整数A,B(0<a,b<n),表示编号为a和b的两点之间有连线。< p="">

Output

如果存在符合条件的连线,则输出"Yes", 如果不存在符合条件的连线,输出"No"。

注意输出不包含引号!

Sample Input

2 4 3 1 2 1 3 1 4 4 5 1 2 2 3 1 3 1 4 3 4

Sample Output

No Yes

HINT

Source

河南理工大学第五届ACM程序设计竞赛

还好这题不吭

#include <stdio.h>
#include <string.h>

#define maxn 1010
int in[maxn], pre[maxn];

int ufind(int x) {
int a = x, b;
while (pre[x] != -1) x = pre[x];
while (a != x) {
b = pre[a];
pre[a] = x;
a = b;
}
return x;
}

bool unite(int x, int y) {
x = ufind(x);
y = ufind(y);
if (x == y) return false;
pre[x] = y;
return true;
}

int main() {
int T, n, m, u, v, i, cnt;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
for (i = 0; i <= n; ++i) {
pre[i] = -1; in[i] = 0;
}
cnt = 0;
while (m--) {
scanf("%d%d", &u, &v);
if (!in[u]) ++cnt;
if (!in[v]) ++cnt;
++in[u]; ++in[v];
if (unite(u, v)) --cnt;
}
if (cnt != 1) {
printf("No\n");
continue;
}
cnt = 0;
for (i = 1; i <= n; ++i)
if (in[i] & 1) ++cnt;
if (cnt == 2 || cnt == 0)
printf("Yes\n");
else printf("No\n");
}
return 0;
}

/**************************************************************
Problem: 1250
User: changmu
Language: C++
Result: Accepted
Time:0 ms
Memory:824 kb
****************************************************************/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HPU1250