图论
图的存储
- 邻接矩阵()
- 邻接表(时间复杂度,空间复杂度)
- 邻接链表()
图的遍历
计算无权图或树上最短路、求连通块比较实用。
输出路径可以用乱搞,也可以在松弛的时候记录路径上的上一个点(也可以叫做最短路径树上的父节点)。
输出字典序最小的路径,可以在反图上进行搜索,再根据字典序倒推路径的上一个点。
输出技巧 printf("%5d",x);
右对齐占格,printf("%-5d",x);
左对齐占格。
障碍路线
状态包含位置和朝向。
巧妙地设计转移坐标数组turnx[]={0,1,0,-1};turny[]={1,0,-1,0};
,使向右转恰好是,左转恰好是。
为了使用,要一次性将所有下一个转弯的位置加入队列中,搜到终点直接返回即可。
防止重复的要点:强制至少走一步,不允许原地转弯。
最优贸易
强连通分量缩点+上
纯!厉害吧。
注意到价格很小,考虑到按价格拆点。
先去除所有不能到达的点,可以在反图上或。
表示到达时所经过的点的最低价为能否实现。从起点开始进行,对于遍历到的每个可能状态,用更新答案。如果发现了一个新的可能状态,就把它入队。
关押罪犯
对答案二分,用或染色,自动过滤掉边权不大于答案的边。。
车站分级
直接拓扑排序边会过多,要添加虚拟的中间点,两个级别的车站连边时,上一级别的车站统一向虚拟点连边,再由虚拟点连向下一级别的车站。
这么做的原因是,题目给出的是这样的关系。
回忆我们解数学题时处理这样的条件的过程:。我们可以把它转化为在内的最小值大于在内的最大值。
进行知识迁移,我们把信息转化为。我们不妨设虚拟点的分级为,则信息转化为,上一级别的所有车站的分级大于虚拟点的分级,下一级别所有车站的分级小于虚拟点的分级,这样这道题的难点就解决了。
最短路
优化
被称为策略。若当前入队的顶点的比队头的小,就将这个点从队头插入;否则插入队尾。在随机图上表现得不错,但是在恶意构造出的数据上会表现出的复杂度~~,死得更惨~~。
道路重建
考虑把已经有公路连接的点缩成同一个点,重新建图跑最短路即可。
其实不需要重新建图,把完好的公路的权值改为即可。
INGRED
最暴力的方法是先用计算出任意两点间的最短路,再枚举两个人访问的特殊点,再枚举访问的顺序,更新答案即可。
比较好的方法是利用特殊点比较少的性质,从每个起点开始跑最短路。把每一个点的状态信息扩充,即把已经访问的特殊点记入点本身,或者说是“拆点”,把每一个点拆成个,点表示到点且状态为的最短路。最后枚举两个人分别走过的特殊点,直接计算答案即可。这样之所以能带来速度提升,是因为它把前面暴力方法中连续枚举(即复杂度相乘)的访问顺序变成了分开枚举(复杂度相加)。
计算特殊的最短路时,拆点时很重要的技巧。如飞行路线。