floyd专项刷题笔记

1.AcWing 1125. 牛的旅行 - AcWing

题意: 给你  多个 连通块 要你求出 把全部连通块连接起来的直径(最大边)最小值

分情况:

情况1 : 最大值可能为一个连通块的直径 -- 求出每个连通块的最大值即可(可以先用floyd去更新每个点到其他点的最短距离,然后取一个连通块里的点更新这个连通块里和这点距离最大的值)

情况2: 最大值可能为两个连通块连接之后的新直径 --尽可能的取最小

最后取二者最大值即可

2.343. 排序 - AcWing题库

bool dist 的floyd d[i][j]|=d[i][k]&&d[k][j];

注明:本题解参考acwing本题连接第一个题解 yxy dalao的题解

迭代次数: 就是那 m 组关系中,到第几组关系,能够出现那三种情况中的一种!

题意:这道题就是看这 m 组关系能否确定每个点的位置。

Q:根据m组关系,怎么排队一个点的是否比另一个点靠前呢?

注: floyd有这样一个用途:判断两点之间是否能够到达

判断func:

1.没加入一组关系就跑一遍 floyd,去更新新加入的两组关系能确定的新关系

2.m组关系跑完后,查找两点最近距离,只要不是 INF ,就表示可以到达了

Q:如何判断矛盾?

本题: 是大小关系比较,因此只有单向边,当出现一队双向边的时候 ---就是出现矛盾了

Q:如何输出排序的序列呢?

fun2:

开一个位置数组,如果一个点的位置确定了,那就将该点存到位置数组对应的位置上。
对应的位置就是能达到该点的点数+1(能到达该点的点都排在该点前面)
这样,如果所有的点都确定了,直接输出位置数组就行了!

func2:

将所有点按照 能到达的点数 从小到大排序。然后依次输出编号。

特别注意:

1.只有两端点权值变小 ,没必要跑完整floyd,只需要用这两个点去更新与他们关联的点即可

2.但是if边权变大,则需要更新初始化dist,跑完整floyd。

(当边权变大,之前的点是用边权变小去更新的,和这个边权变大的更新方式不一样)

so遇到这样问题的处理,最好是统一方向< or >

3.344. 观光之旅 - AcWing题库

以下解释:参考链接题解第一篇

前提:设 三点,i,j,k组成一个环

floyd特性 -- 插点

每次插入一个点k,在k被插入后,我们就可以计算出 i-j-k 这个环

此时已经经过了1-k-1 这些中间节点,我们此时算出的i,j最短距离就是经过这些点算出的

那么我们只需要枚举所有 以 k为环中最大节点的环即可

然后引入pos数组记录中间节点即可:

pos[i][j]:i->j的最短路中经过的点是k
(即由这个状态转移过来),且这个k是此路径中编号最大的点(除i,j)
//根据Floyd算法实质决定
这条道路存在以下两条性质
1.在i~j的最短道路中,一定没有环(显然)
2.设i,j之间的最短道路经过点k(不同于i,j),则i~k , k~j之间必然没有交集

4.345. 牛站 - AcWing题库

本体标签:类floyd +qmi(快速幂)

//改变floyd算法定义方式:
一经般: d[k][i][j]--表示从 i到j值经过1-k编号的点的话,最短路径是多少
 改变:d[k][i][j]--表示从i到j,切好过k条边的最短路径
得到状态转移方程: d[a+b][i][j]=min(d[a+b][i][j],d[a][i][k]+d[b][k][j]),k=1->n;

证明:

 那么由上定义我们知道: 当k取从1-n的时候我们就得到了i,j的最短路径了--这不就是floyd嘛

so每次求S到E的最短路径需要O(N^3)if再限制边数为m则需要 m*N^3的时间复杂度

其实通过观察我们可以发现:

 S-x1-x2-...-xn-E; --满足结合律,矩阵乘法(有结合律)->快速幂
  我们发现路径相互独立--有结合律--可以使用快速幂求

由于满足结合律,结果相互独立我们 只需要求出最终d[m][S][E] 即可,那么我们可以 使用(qmi)倍增代替逐个递增-- 优化为O(log(m)N^3)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值