您的位置:首页 > 其它

nyoj42一笔画问题

2013-11-11 18:02 183 查看

一笔画问题

时间限制:3000 ms | 内存限制:65535 KB

[align=center]难度:4[/align]

[align=left] 描述 [/align]

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


分析:

根据输入数据,用邻接表建图,判断图是否连通, 若不连通,直接输出No,若连通,再判断所有顶点的度数,若奇度顶点的个数为0或2,则能一笔画出,否则不能。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

struct Node
{
int v;
struct Node *next;
};

struct Mgrage
{
Node *head;
};

Mgrage map[2001];
bool visit[2001];
int f;

void init_map()//初始化
{
for (int i = 0; i < 2001; i++)
{
map[i].head = NULL;
}
}

void insert(int x, int y)//邻接表建图
{
Node *p, *q;
p = (Node *)malloc(sizeof(Node));
p->v = y;
p->next = NULL;
q = map[x].head;
if (q == NULL)
map[x].head = p;
else
{
while (q->next != NULL)
q = q->next;
q->next = p;
}
}

void dfs(int x)//深搜判断图的连通性
{
visit[x] = 1;
if (map[x].head == NULL)
return ;
Node *p = map[x].head;
while (p != NULL)
{
if (!visit[p->v])
{
visit[p->v] = 1;
dfs(p->v);
}
p = p->next;
}
}

int main()
{
int n;
scanf("%d", &n);
while (n--)
{
f = 0;
memset(visit, 0, sizeof(visit));
init_map();
int P, Q;
int s = 0;
scanf("%d%d", &P, &Q);
for (int i = 1; i <= Q; i++)
{
int k, l;
scanf("%d%d", &k, &l);
insert(k, l);
insert(l, k);
}
dfs(1);
for (int i = 1; i <= P; i++)
{
if (visit[i] == false)
{
f = 1;
break;
}
}
if (f == 1)//图不连通
{
printf("No\n");
continue;
}
for (int i = 1; i <= P; i++)
{
int sum = 0;
Node *p = map[i].head;
while (p != NULL)
{
sum++;
p = p->next;
}
if (sum % 2 != 0)
{
s++;//奇度顶点的个数
}
}
if (s == 0 || s == 2)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: