P1636 Einstein学画画

P1636 Einstein学画画

题目描述

Einstein学起了画画,

此人比较懒~~,他希望用最少的笔画画出一张画。。。

给定一个无向图,包含n 个顶点(编号1~n),m 条边,求最少用多少笔可以画出图中所有的边

输入输出格式

输入格式:

第一行2个数n,m

以下m行 每行2个数a,b(a<>b) 表示a,b两点之间有一条边相连

一条边不会被描述多次

输出格式:

一个数 即问题的答案

输入输出样例

输入样例#1:
5 5
2 3
2 4
2 5
3 4
4 5
输出样例#1:
1

说明

约定 50%的数据n<=50,m<=100

100%的数据n<=1000,m<=100000

分析:

一笔画判断:奇点数为2或0或大于2且不被2整除的图

X笔画判断: 奇点数为1及2以上的图,奇点数为N,则X=N整除2

本题其实就是考察简单半欧拉图及其扩展定理,设顶点的度数为连接的边数,然后统计所有顶点中度数为奇数的顶点的个数n,则答案一定为n/2。

首先,根据握手定理,所有顶点的度数之和一定为偶数。则奇数顶点的个数一定为偶数。然后每画一笔,最多可以使奇数顶点个数减少两个(或者不减少),所以一定至少要n/2笔,才能把画画完。

有一个特殊情况,即为所有点构成一个环的情况。此时n=0,但实际上需要一笔画完(即欧拉图),所以需要特判一下。

这个题目如果部分点成环了怎么办??

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 int b[10001];
 5 int main()
 6 {
 7     //freopen("in.txt","r",stdin); 
 8     int n,m,i,j,k,geshu=0,x,y;
 9     scanf("%d%d",&n,&m);
10     for (i=1;i<=m;i++)//运用定理
11     {
12     //运用定理 
13     scanf("%d%d",&x,&y);//运用定理
14     b[x]++;//运用定理
15     b[y]++;//运用定理
16     }
17     //运用定理
18     for (i=1;i<=n;i++)
19         if (b[i]%2==1)//判断度数
20             geshu++;
21     if (geshu)
22         printf("%d",geshu/2);
23     else//特判
24         printf("%d",geshu+1);
25 }
原文地址:https://www.cnblogs.com/Renyi-Fan/p/7623089.html