图论
最短路:dijkstra spfa floyd
最小生成树:kruskal
连通性:bfs/dfs tarjan(强连通分量)
其它:拓扑排序 LCA
齿轮:
图的dfs树只有返祖边没有横向边
树边确定了基础的转动比,非树边判定转动比是否可行
Lca
Dijkstra
Pair第一个存的是源点到这个点当前的最短路,第二个存的是这个点的编号
预处理 把1压进去,1到其他的dis都设置为正无穷
不断地从堆顶弹出元素,直到弹空
对其中的元素进行处理
注意如果已经处理过就不用处理了
Spfa
先建一个循环队列或者stl队列,如果不为空就继续运行
每次从队首取出一个元素,标记这个元素不在队列里
枚举所有的出边,如果满足不等式就更新
循环队列:重复利用空间,方便查找bug
//最长路
Floyd
枚举所有中间节点进行扩展
先枚举中间节点
Kruscal
最小生成树的最大边权一定最小
先把所有边权拿出来排序,每次选取边权最小的一条边,把两个端点放在同一个连通块当中
如果两个端点已经在一个连通块中就跳过
并查集了解一下
注意是无向图
拓扑排序
每次删去一个没有入度的节点
考法:拓扑序上dp 判环
Telephone lines
二分答案
边权小于mid相当于会被花费覆盖掉,边权大于mid必须让他免费
考虑从点1到n可不可以有小于k条边权大于mid的边
让大于mid边权为1,小于等于mid边权为0
如果最短路的dis<=k,就说明这个解可行
Revamping trails
分层建图,每一层表示升级了几条路
把有边的两点上下两层分别连一条边权为0的边,点m向上面一层连一条边权为0的点
相当于搞一个映射把二维映射成一维
第k层第i个点(k,i)->(k-1)*n+i
只需要搞一个函数d(k,i)
Wormholes
Spfa判负环
看入队次数
Meeting
这道题难点在建图
我们多建一些点,表示每一个集合,然后把这一个街区内的点用边权为val[i]的有向边指向这个点,再用边权为0的有向边指回来,然后跑dijkstra就好了
寻宝游戏
先考虑离线算法
按照树的dfs序走
按dfs序排序,求出两两之间的lca,求出两个点之间的最短路
在线:比如在i,j中插入点k(字典序),就可以在原来的基础上减去i,j的距离(用lca求)加上i,k的距离和k,j的距离就行了
我们只需要知道插入的数k的前驱和后继,直接用set
复杂度 o(n+mlogn)
飞飞侠
让它飞起来(雾
考虑在这个点上方b[i][j]的点连边,往四周飘,每一次低一格(因为曼哈顿距离)。在每一个点往直下方连边,表示在这个点降落
三维分层图跑三遍最短路就行了