11.6 训练参考
本章的篇幅不长,内容也不多,不过非常重要。考虑到介绍图论算法的书籍和文章很多,本章并没有很正式地介绍各种概念、算法的证明以及严格的复杂度分析,而是把重点放在了程序实现技巧和建模技巧上。本章例题大都不难,建议读者除了掌握不带星号的题目之外也努力弄懂带星号的题目,并且编程实现。例题列表如表11-1所示。
表11-1 例题列表
| 类别 | 题号 | 题目名称(英文) | 备注 |
| 例题11-1 | UVa12219 | Common Subexpress ion Elimination | 表达式树 |
| 例题11-2 | UVa1395 | Slim Span | 最小生成树 |
| 例题11-3 | UVa1151 | Buy or Build | 最小生成树 |
| 例题11-4 | UVa247 | Calling Circles | Floyd算法、连通分量 |
| 例题11-5 | UVa10048 | Audiophobia | Floyd算法,最大值最小路 |
| 例题11-6 | UVa658 | It's not a Bug, it's a Feature! | 复杂状态的最短路 |
| 例题11-7 | UVa753 | A Plug for UNIX | Floyd算法、二分图最大匹配 |
| 例题11-8 | UVa11082 | Matrix Decompress ing | 网络流建模 |
| 例题11-9 | UVa1658 | Admiral | 拆点法,最小费用流 |
| 例题11-10 | UVa1349 | Optimal Bus Route Design | 后继模型;二分图最小权匹配 |
| 例题11-11 | UVa12661 | Funny Car Racing | 特殊图的Dijkstra算法 |
| *例题11-12 | UVa1515 | Pool construction | 最小割模型 |
| *例题11-13 | UVa10735 | Euler Circuit | 网络流建模 |
| *例题11-14 | UVa1279 | Asteroid Rangers | 动点的最小生成树 |
| *例题11-15 | UVa1659 | Help Little Laura | 最小费用循环流 |
下面是习题。本章的习题大都不难,建议读者至少完成10道题目。如果要达到更好的效果,至少需要完成15道题目。
习题11-1 网页跳跃(Page Hopping, ACM/ICPC World Finals 2000, UVa821)
下面是习题。本章的习题大都不难,建议读者至少完成10道题目。如果要达到更好的效果,至少需要完成15道题目。
最近的研究表明,互联网上任何一个网页在平均情况下最多只需要单击19次就能到达任意一个其他网页。如果把网页看成一个有向图中的结点,则该图中任意两点间最短距离的平均值为19。
输入一个n(1≤n≤100)个点的有向图,假定任意两点之间都相互到达,求任意两点间最短距离的平均值。输入保证没有自环。
习题11-2 奶酪里的老鼠(Say Cheese, ACM/ICPC World Finals 2001, UVa1001)
无限大的奶酪里有n(0≤n≤100)个球形的洞。你的任务是帮助小老鼠A用最短的时间到达小老鼠O所在位置。奶酪里的移动速度为10秒一个单位,但是在洞里可以瞬间移动。洞和洞可以相交。输入n个球的位置和半径,以及A和O的坐标,求最短时间。
习题11-3 因特网带宽(Internet Bandwidth, ACM/ICPC World Finals 2000, UVa820)
图11-18 计算机和路径
在因特网上,计算机是相互连通的,两台计算机之间可能有多条信息连通路径。流通容量是指两台计算机之间单位时间内信息的最大流量。不同路径上的信息流通是可以同时进行的。例如,图11-18中有4台计算机,总共5条路径,每条路径都标有流通容量。从计算机1到计算机4的流通总容量是25,因为路径1-2-4的容量为10,路径1-3-4的容量为10,路径1-2-3-4的容量为5。
请编写一个程序,在给出所有计算机之间的路径和路径容量后求出两个给定结点之间的流通总容量(假设路径是双向的,且两方向流动的容量相同)。
习题11-4 电视网络(Cable TV Network, ACM/ICPC SEERC 2004, UVa1660)
给定一个n(n≤50)个点的无向图,求它的点连通度,即最少删除多少个点,使得图不连通。如图11-19所示,图11-19(a)的点连通度为3,图11-19(b)的点连通度为0,图11-19(c)的点连通度为2(删除1和2或者1和3)。
|
| |
| (a) | (b) | (c) |
图11-19 点的连通度
习题11-5 方程(Equation, ACM/ICPC NEERC 2007, UVa1661)
输入一个后缀表达式f(x),解方程f(x)=0。表达式包含四则运算符,且x最多出现一次。保证不会出现除以常数0的情况,即至少存在一个x,使得f(x)不会除0。所谓后缀表达式,是指把运算符写在运算数的后面。例如,(4x+2)/2的后缀表达式为4x * 2 + 2 /。样例输入与输出如表11-2所示。
表11-2 样例输入与输出
| 样例输入 | 样例输出 |
| 4 X * 2 + 2 / | X = -1/2 |
| 2 2 * | NONE |
| 0 2 X / * | MULTIPLE |
习题11-6 括号(Brackets Removal, NEERC 2005, UVa1662)
给一个长度为n的表达式,包含字母、二元四则运算符和括号,要求去掉尽量多的括号。去括号规则如下:若A和B是表达式,则A+(B)可变为A+B,A-(B)可变为A-B',其中B'为B把顶层“+”与“-”互换得到;若A和B为乘法项(term),则A*(B)变为A*B,A/(B)变为A/B',其中B'为B把顶层“*”与“/”互换得到。本题只能用结合律,不能用交换律和分配律。
例如,((a-b)-(c-d)-(z*z*g/f)/(p*(t))*((y-u)))去掉括号以后为a-b-c+d-z*z*g/f/p/t*(y-u)。
习题11-7 电梯换乘(Lift Hopping, UVa 10801)
在一个假想的大楼里,有编号为0~99的100层楼,还有n(n≤5)座电梯。你的任务是从第0楼到达第k楼。每个电梯都有一个运行速度,表示到达一个相邻楼层需要的时间(单位:秒)。由于每个电梯不一定每层都停靠,有时需要从一个电梯换到另一个电梯。换电梯时间总是1分钟,但前提是两座电梯都能停靠在换乘楼层。大楼里没有其他人和你抢电梯,但你不能使用楼梯(这是一个假想的大楼,你无须关心它是否真实存在)。
例如,有3个电梯,速度分别为10、50、100,电梯1停靠0、10、30、40楼,电梯2停靠0、20、30楼,电梯3停靠第0、20、50楼,则从0楼到50楼至少需要3920秒,方法是坐电梯1到达30楼(300秒),坐电梯2到达20楼(500秒+换乘60秒),再坐电梯3到达50楼(3000秒+换乘60秒),一共300+50+60+3000+60=3920秒。
习题11-8 净化器(Purifying Machine, ACM/ICPC Beijing 2005, UVa1663)
给m个长度为n的模板串。每个模板串包含字符0,1和最多一个星号“*”,其中星号可以匹配0或1。例如,模板01*可以匹配010和011两个串,而模板集合{*01, 100, 011}可以匹配串{001, 101, 100, 011}。
你的任务是改写这个模板集合,使得模板的个数最少。例如,上述模板集合{*01, 100, 011}可以改写成{0*1, 10*},匹配到的字符串集合仍然是{001, 101, 100, 011}。n≤10,m≤1000。
习题11-9 器人警卫(Sentry Robots, ACM/ICPC SWERC 2012, UVa12549)
在一个Y行X列(1≤Y,X≤100)的网格里有空地(.),重要位置(*)和障碍物(#),如图11-20所示。用最少的机器人看守所有重要位置。每个机器人要放在一个格子里,面朝上下左右4个方向之一。机器人会发出激光,一直射到障碍物为止,沿途都是看守范围。机器人不会阻挡射线,但不同的机器人不能放在同一个格子。
图11-20 “机器人警卫”问题示意图
习题11-10 Risk游戏(Risk, NWERC 2010, UVa12011)
有n(n≤100)个阵地。已知我方在每个阵地上的士兵数(0~100的整数),其中士兵大于0表示该阵地由我方占领,否则为敌方占领。对于一个我方阵地,如果其相邻的阵地中有敌方阵地,则称为边界阵地(border region)。
现在对我方士兵进行调动(每次可以把一个士兵从一个阵地移动到相邻的我方阵地,操作可以进行任意多次),在保证我方不丢失阵地的情况下(即我方每个阵地上的人数不为0),使得我方的边界阵地中人数最少的阵地的人数尽量多。
输入保证我方至少有一个阵地,敌方也至少有一个阵地,且至少有一个我方阵地与敌方阵地相邻。
习题11-11 占领新区域(Conquer a New Region, ACM/ICPC Changchun 2012, UVa1664)
n(n≤200000)个城市形成一棵树,每条边有权值C(i,j)。任意两个点的容量S(i,j)定义为i与j唯一通路上容量的最小值。找一个点(它将成为中心城市),使得它到其他所有点的容量之和最大。
习题11-12 岛屿(Islands, ACM/ICPC CERC 2009, UVa1665)
输入一个n*m矩阵,每个格子里都有一个[1,109]正整数。再输入T个整数ti(0≤t1≤t2≤…≤tT≤109),对于每个ti,输出大于ti的正整数组成多少个四连块。如图11-21所示,大于1的正整数组成两块,大于2的组成3块。
评论:这个题目虽然和图论没什么关系,但是可以用到本章介绍的某个数据结构。
| ![]() |
图11-21 “岛屿”问题示意图
习题11-13 最短路线(Walk, ACM/ICPC Jinhua 2012, UVa1666)
平面上有n(n≤50)个建筑物,求从(x1,y1)到(x2,y2)的一条路,使得转弯次数最少。建筑物都是坐标平行于坐标轴的矩形,可以相互接触但不会重叠(接触的点或者边都不能通过)。你只能沿着平行于坐标轴的直线走,可以沿着建筑物的边走,但不能穿过建筑物。无解输出-1。
提示:本题在细节上容易出错。
习题11-14 乱糟糟的网络(Network Mess, ACM/ICPC Tokyo 2005, UVa1667)
有一棵n(n≤50)个叶子的无权树。输入两两叶子的距离,恢复出这棵树并输出每个非叶子结点的度数。
习题11-15 绿色行动(Let's Go Green, ACM/ICPC Jakarta 2012, UVa1668)
输入一棵n(2≤n≤100000)个结点的树,每条边上都有一个权值。要求用最少的路径覆盖这些边,使得每条边被覆盖的次数等于它的权值,如图11-22所示。
| ![]() |
图11-22 “绿色行动”问题示意图
习题11-16 交换房子(Holiday's Accomodation, ACM/ICPC Chengdu 2011, UVa1669)
有一棵n(2≤n≤105)个结点的树,每个结点住着一个人。这些人想交换房子(即每个人都要去另外一个人的房子,并且不同人不能去同一个房子)。要求安排每个人的行程,使得所有人旅行的路程长度之和最大。
习题11-17 王国的道路图(Kingdom Roadmap, ACM/ICPC NEERC 2011, UVa1670)
输入一个n(n≤100000)个结点的树,添加尽量少的边,使得任意删除一条边之后图仍然连通。如图11-23所示,最优方案用虚线表示。
图11-23 “王国的道路图”问题示意图
习题11-18 交通堵塞(Traffic Jam, ACM/ICPC Dhaka 2009, UVa12214)
有一条包含n(1≤n≤25)段的单向折线,你想开着一辆会“飞”的车从折线起点到折线终点,且耗油量最少。沿着折线方向正常行驶时单位耗油量为1,“飞行”时单位耗油量为f(2≤f≤5)。如图11-24所示,f=2,折线为(0,0)-(2,2)-(2,-2),沿折线行驶的耗油量为2.828+4=6.828,最优解是从(0,0)“飞”到(2,-1.154),然后正常行驶到(2,-2),耗油量为2*2.309+0.846=5.464。
图11-24 行驶路线
习题11-19 火车延误(Train Delays, NWERC 2011, UVa1518)
有n(1≤n≤100)条火车线路,均为每小时发车一次。输入每条线路的起点站和终点站名称、发车时间m(0≤m≤59)、正点运行时间t(1≤t≤300)、到达时间、延误概率百分比p(0≤p≤100)和最大延误时间d(1≤d≤120)。如果火车延误,实际延误时间为[1,d]内均匀分布的整数,并且只有在列车发车之后才能知道是否会延误(但此时已经无法换车)。
假定换乘不花时间(即使到达时刻等于要换乘的列车的发车时刻,也可以完成换乘),并且可以根据实际延误情况动态改变乘车计划,你的任务是让总时间的期望值最小。出发时间可以自己定。
习题11-20 租车(Rent a Car, UVa12433)
你想经营一家租车公司。接下来的N天中已经有了一些订单,其中第i天需要rj辆车(0≤rj≤100)。初始时,你的仓库是空的,需要从C家汽车公司里买车,其中第i家公司里有ci辆车,单价是pi(1≤ci,pi≤100)。当一辆车被归还给租车公司之后,你必须把它送去保养之后才能再次租出去。一共有R家服务中心,其中第i家保养一次需要di天,每辆车的费用为si(1≤di,si≤100)。这些服务中心都很大,可以接受任意多辆车同时保养。你的仓库很大,可以容纳任意多辆车。你的任务是用最小的费用满足所有订单。1≤N,C,R≤50。
例如,N=3,C=2,R=1,r={10,20,30},c1=40,p1=90,c2=15,p2=100。d1=1,s1=5,最优方案是:先买50辆车,其中在公司1买40辆,公司2买10辆,费用为90*40+100*10=4600。第一天白天租出去10辆车,晚上收回之后送到服务中心保养一天,费用为5*10=50,第3天白天可以再次出租。第2天出租20辆车,第3天把剩下的20辆车和保养后的10辆车一起出租。总费用为4600+50=4650。
习题11-21 矩阵中的符号(Sign of Matrix, UVa11671)
有一个n*n(2≤n≤100)的全零矩阵,每次可以把某一行的所有元素加1或减1,也可以把某一列的所有元素加1或减1。操作之后每个元素的正负号已知,问:至少需要多少次操作?无解输出-1。例如,要达到图11-25(a)中的正负号矩阵,至少需要3次操作,如图11-25(b)所示。
| ![]() |
| (a) | (b) |
图11-25 正负号矩阵与操作后结果