一、基础题目
1、UVA 11624 Fire!迷宫问题 多源BFS
题意:
帮助joe走出一个大火蔓延的迷宫,其中joe每分钟可往上下左右四个方向之一走,所有着火的格子都会蔓延(空格与着火格有公共边,下一分钟这个空格也会着火)。迷宫中有一些障碍格,joe和火都无法进入,当joe走到一个边界的格子我们认为他走出了迷宫
输出R行C列的迷宫,#表示墙,.表示空地,J表示joe,F是着火格
如果能走出,输出最少时间否则,impossible
思路:
先预处理出每个点的起火时间,可以用多源点BFS直接处理出来
再用BFS求从出发点到边界的最短路,每次扩展点的时候保证走到该点的时间严格小于该点起火时间
代码:
https://paste.ubuntu.com/p/R4bpSJDGvP/
2、UVA 10047 The Monocycle 迷宫问题 复合状态
题意:
从起点到终点,每秒可以选择前进、向左、向右转, 每前进一格轮子转到下一个颜色, 一共5种颜色, 开始的时候绿色接触地面,朝北, 要求最后也绿色接触地面,求能否到达目标点以及最短时间。
思路:
BFS 多了两维状态 直接模拟即可
代码:
https://paste.ubuntu.com/p/QRDxqFxN6F/
3、UVA 10054 The Necklace 欧拉回路
题意:
n个珠子,每个珠子的两半由不同的颜色组成。 只有相同的颜色才能接在一起, 问能否组成一个一个项链。
思路:
判断每个点的度数均为偶数个,判断图联通,注意有重边。然后用刘汝佳的欧拉回路模板即可。
代码:
https://paste.ubuntu.com/p/9VPsbRh53M/
4、UVALive 4255 Guess 拓扑排序
题意:
对于一个序列a1,a2,a3,….an,我们可以计算出一个符号矩阵S,就是上面右图矩阵,其中S(i,j)表示 ai+…+aj的正负号,给出序列不难求出矩阵,我们的任务是求出“逆问题”,即给出矩阵,求出序列,序列每个值大于-10小于10;
思路:
拓扑排序即可,主意需要用Kahn算法进行拓扑排序,因为有多个入度为0的点的话,必须设置成权值一样的点。
代码:
https://paste.ubuntu.com/p/VwF7NcWZnx/
二、DFS的应用
二分图判定 无向图割顶和桥 无向图双连通分量 有向图强连通分量 2-SAT问题
1、UVAlive 3523 Knights of the Round Table 二分图+双连通分量
题意:
有n(n≤1000)个骑士,m(m≤1000000)对骑士互相憎恨,要3个以上的骑士且保证互相憎恨的骑士不会坐在相邻位置才能开会议,求多少骑士一定不能参加任何一次会议。
思路:
首先建图,两个骑士可以相邻,那么就连边。那么题目转化成求不在任何一个简单奇圈上的节点的个数。如果图G不连通,那么分成几个连通分量来求解。
假设图G连通,那么简单圈上的点必然属于一个双连通分量,所以先找出所有双连通分量。
二分图的充要条件是没有奇圈,可以很明显的得到:如果一个双连通分量是二分图,那么里面的点一定不在奇圈上。
如果一个双连通分量不是二分图,那么里面的点会在奇圈上吗?
答案是一定在奇圈上,首先双连通分量不是二分图,那么里面一定存在一个奇圈C。对于这个连通分量里面的点,有两种状态,在C上和不在C上。
在C上的话,本身C就是一个奇圈
不在C上的话,可以构造出一个奇圈出来。在C上取两点u1和u2,u1到u2有两条不相交路径,并且长度为一奇一偶,对于C外的任意一点v,由于是在双连通分量内,v到u1,v到u2有不相交的两条路径,这样的话,由于u1到u2之间既有偶数长度的路径,也有奇数长度的路径,所以v一定可以和u1 u2构造出奇圈出来。
整理一下思路就是首先求出所有的双连通分量,再判断这个双连通分量是不是二分图,如果不是二分图,那么该连通分量里面的点都为可以在奇圈的点,处理出所有可以在奇圈上的点之后,再算出不可以在奇圈上的点的数目即可。
代码:
https://paste.ubuntu.com/p/KjYRQ2rDwR/
2、UVAlive 5135 Mining Your Own Business 双连通分量 割顶
题意:
一座地下稀有金属矿由n条隧道和一些连接点组成,每条隧道连接两点。任意两点之间最多一条隧道。你的任务是在一些连接点处安装逃生装置,使得不管哪个连接点倒塌,不在此连接点的所有矿工都能到达太平井逃生。为了节约成本,你应当在尽量少的连接点安装太平井。输出数目和方案数。
思路:
本题模型:在无向图上选择尽量少的点涂黑,使得任意删除一个点后每个连通分量至少有一个黑点。
可以这样想,如果删除点是割点,那么割点会把图分成几个连通分量,那么至少需要这么多个黑点。
最优策略是对于一个点-双连通分量中如果只有一个割点,那么这里面必须选一个染黑,染黑方法为除了割点之外的点任选一个即可。
特殊情况:只有一个双连通分量,此时一定没有割点,因为割点是至少两个不同双连通分量的公共点。那么任意染黑两个点即可。
代码:
https://paste.ubuntu.com/p/vVDvKv8XhS/
3、UVAlive 4287 Proving Equivalences 强连通分量 缩点
题意:
给出n个点,m条边,问最少添加多少条边,使得有向图为强连通
思路:
缩点,构成新图DAG,在新图上,入度为0的点数目为a,出度为0的点数目为b,ans = Max(a, b),特判,如果本来就是强连通的,那么ans = 0
代码:
https://paste.ubuntu.com/p/q2RTbKv26y/
4、UVA 11324 The Largest Clique 强连通分量 缩点 DP
题意:
给一张有向图G,求一个节点数最大的节点集合,使得该集合中任意两个点u和v满足,要么u可以到达v,要么v可以到达u。(u、v相互到达也可以)
思路:
最优解中,同一个强连通分量中的点,要么全选,要么全不选。所以可以缩点,构造出DAG图,图上每个点的价值为这个强连通分量里面的点的个数。然后用记忆化搜索求出最大权值的路径即可。
代码:
https://paste.ubuntu.com/p/YrpPGbpM46/
5、UVAlive 3211 Now or later 二分 2-SAT
题意:
n架飞机,每架可选择两个着落时间。安排一个着陆时间表,使得着陆间隔的最小值最大。
思路:
二分着陆间隔最小值,用2-SAT判定
对于i飞机的a状态和j飞机的b状态,如果他们之间的距离小于二分的值,说明不能满足二分的最小值,所以a状态和b状态不能同时存在,所以在2-SAT中添加i = !a or j = !b的判定条件。