《趣题学算法》—第1章1.4节图的性质

简介:

本节书摘来自异步社区《趣题学算法》一书中的第1章1.4节图的性质,作者徐子珊,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 图的性质
有的计数问题所涉及的事物间存在着某种关系,这样的问题往往可以表示成一个图(Graph):问题中的每个事物视为一个顶点,两个顶点之间如果存在这关系,就在这两个顶点之间做一条称为边的弧。形式化描述为由问题中的各事物构成的集合,记为顶点集V={v1,v2,…,vn},边集E={(vi, vj)| vi, vj ∈V且vi和vj具有关系}。

例如,图1-3将五个人Adward、John、Philips、Robin和Smith之间的朋友关系表示成了一个图。其中,Adward与Robin和Smith是朋友,John与Philips和Robin是朋友,Philips与John、Robin和Smith是朋友,Smith与Adward、Philips和Robin是朋友,Robin与其他所有人都是朋友。


3f5ec86e621059eee5612250093f7c795738cb3d

图G记为。数学家们对图的研究已经有了百年的历史,有很多很好用的性质能帮助我们轻松地解决计数问题。例如,图论中有一个著名的“握手”定理。

定义1-1

设G=为一无向图,vV,称v作为边的端点次数之和为v的度数,简称为度,记为d(v)。

对图中所有顶点的度数有如下所述的结论。

定理1-1(握手定理)

设G=为任意无向图,V={v1,v2,…,vn},|E|=m,则

sumnolimits_{i=1}^{n}{d({{v}_{i}})=2m}

即所有顶点的度数之和为边数的2倍。

证 G中每条边(包括环)均有两个端点,所以在计算G中各顶点度数之和时,每条边均提供2度,当然,m条边,共提供2m度。

握手定理说明,图中各顶点的度数之和必为偶数。


3f699573f87b978950fdd06311592a1a0fcc34c6

问题描述

百度之星总决赛既是一群编程大牛一决高下的赛场,也是圈内众多网友难得的联欢,在为期一周的聚会中,总少不了各种有趣的游戏。

某年的总决赛聚会中,一个有趣的游戏是这样的:

游戏由Robin主持,一共有N个人参加(包括主持人),Robin让每个人说出自己在现场认识的人数(如果A认识B,则默认B也认识A),在收到所有选手报出的数据后,他来判断是否有人说谎。Robin说,如果他能判断正确,希望每位选手都能在毕业后来百度工作。

为了帮Robin留住这些天才,现在请您帮他出出主意吧。

特别说明:

1.每个人都认识Robin。

2.认识的人中不包括自己。

输入

输入数据包含多组测试用例,每组测试用例有2行,首先一行是一个整数N (1

N为0的时候结束输入。

输出

请根据每组输入数据,帮助主持人Robin进行判断:如果确定有人说谎,请输出“Lie absolutely”;否则,请输出“Maybe truth”。

每组数据的输出占一行。

输入样例

7
5 4 2 3 2 5
7
3 4 2 2 2 3
0

输出样例

Lie absolutely
Maybe truth

解题思路

(1)数据的输入与输出

根据题面中对输入文件格式的描述,文件中有若干个测试案例,每个案例的数据以表示人数的整数N开头,然后有N-1个整数表示除主持人以外的每个人所报告的相识人数。对案例判断其中是否有人说谎,根据计算结果输出一行“Maybe truth”(无人说谎)或“Lie absolutely”(有人说谎)。N=0是输入结束的标志。

1 打开输入文件inputdata
2 创建输出文件outputdata
3 从inputdata中读取人数N
4 while N≠0
5   do 创建数组a[1..N]
6     for i←1 to N-1
7        do 从inputdata中读取a[i]
8     a[N] ←N-1  ▷Robin认识每个人
9     result← PARTY-GAME(a)
10    if result=true
11       then 将"Maybe truth"作为一行写入outputdata
12       else将"Lie absolutely"作为一行写入outputdata
13    从inputdata中读取案例数据N
14 关闭inputdata
15 关闭outpudata

其中,第9行调用过程PARTY-GAME(a)判断N个人中是否有人说谎,是解决一个案例的关键。

(2)处理一个案例的算法过程

在一个案例中,把两个人相互认识看成一种关系,n个人之间的认识关系将可表示成一个无向图G=。其中,顶点集V={v1,v2,…,vn}表示这n个人,边集E中元素表示两个人之间的认识关系。

利用握手定理,我们将问题中的每一个案例的所有人所报的认识的人数(包括主持人报的n−1)相加,考察和数的奇偶性,若为奇数,则肯定有人撒谎。等价地,设置一个计数器count(初始为0),检测每个人(包括主持人)所报的认识的人数,若是奇数则count增加1,根据count的奇偶性进行判断。伪代码过程表示为如下:

PARTY-GAME(a)
1 n←length[a]    
2 count←0
3 for i←1 to n   ▷检测每一个人报告的认识人数
4     do if a[i] is odd
5          then count←count+1
6 return count is even

算法1-11 利用握手定理判断晚会中是否有客人说谎的过程

对一个案例而言,假定包括主持人在内,晚会上有n个人,则第3~5行的for循环将重复n次。所以算法对一个案例的运行时间是Θ(n)。

解决本问题的算法的C++实现代码存储于文件夹laboratory/Party Game中,读者可打开文件partygame.cpp研读,并试运行之。

相关文章
|
6月前
|
算法
数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)
数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)
56 0
|
存储 算法 C语言
二叉树的概念和性质/向上调整、向下调整算法/堆的插入和删除/堆排序/Top-K问题【上】【数据结构/二叉树/初阶/C语言实现】
二叉树的概念和性质/向上调整、向下调整算法/堆的插入和删除/堆排序/Top-K问题【上】【数据结构/二叉树/初阶/C语言实现】
63 0
|
机器学习/深度学习 算法 数据挖掘
【数据挖掘】关联规则挖掘 Apriori 算法 ( 关联规则性质 | 非频繁项集超集性质 | 频繁项集子集性质 | 项集与超集支持度性质 )
【数据挖掘】关联规则挖掘 Apriori 算法 ( 关联规则性质 | 非频繁项集超集性质 | 频繁项集子集性质 | 项集与超集支持度性质 )
381 0