[OO] JML系列 优化及时间复杂度可行性证明
企业开发
2020-05-15 10:20:05
阅读次数: 0
JML系列 优化及时间复杂度可行性证明
符号定义
符号 |
意义 |
上限 |
p |
网络中Person数量 |
800 |
r |
网络中关系数量 |
3000 |
qs |
查询queryStrongLinked数量 |
20 |
qr |
查询queryNameRank数量 |
1000 |
qb |
查询queryBlockSum数量 |
3000 |
qa |
查询queryAgeSum数量 |
3000 |
qm |
查询queryMinPath数量 |
3000 |
优化方法与复杂度分析
queryBlockSum
- 由于不需要删除操作,故采用并查集实现
- 并查集单次操作的均摊复杂度为
O(α(n)),其中
α为一个Ackerman函数相关的,这里可以认为小于常数
4
- 每次查询时需遍历每个Person,时间复杂度
O(αp)
- 动态维护加边的复杂度
O(αr)
- 总时间复杂度
O(αpqb+αr)上限小于
1×107,稳妥
queryAgeSum
- 采用直接暴力枚举Person进行计数的方法
- 时间复杂度为
O(qap),上限
2.4×106,稳妥
queryNameRank
- 采用每次查询直接暴力统计的方法
- 时间复杂度
O(qrp),上限
8×105,稳妥
queryMinPath
- 采用堆优化Dijkstra算法,因为不需要处理负环
- 单次单源最短路径时间复杂度
O((p+r)logr)
- 总体时间复杂度为
O(qm(p+r)logr),上限较大,但由于总指令数限制,还满足关系
qm+p+r≤3000,求极值可估计真实复杂度上限小于
2.5×107
- 注意此题不写堆优化上限可达
1×109大概率被卡
- 另外spfa已死,不卡是情分,卡是本分,参考NOI2018Day1T1,这本来也是一种及其不稳定的算法
queryStrongLinked
暴力枚举
- 这种做法需要两步bfs/dfs
- 第一次判断连通后,枚举去掉所有割点再次bfs判断是否仍然联通,如果都能联通,说明这两个点点双连通
- 这里的枚举割点是准确条件,但实现的时候如果不想再写一个找割点的算法(还是Tarjan),可以用枚举所有点替代
- 第二次bfs采用MASK的方法加速,不需要修改原图
- 总时间复杂度
O(qsp(p+r))时间复杂度上限可达
4.8×107,应该能过,但有些小小的危险,如果具体实现太丑有可能被卡常,
不过相信课程组是善良的
- 【更新】:经大佬指点,发现只需要MASK第一次bfs找到的路径上的非首尾点,原因在于双连通是为了找第二条除首尾外无重复节点的路径,MASK第一条路径后如果还能连通,那么必然双连通,复杂度降低为
O(2qs(p+r)),上限在
1.2×105,稳妥地过!
点双连通分量
- 大致思路采用Tarjan找点双连通分量,再判断两个点是否具有相同编号(只是大致思路)
- 单次Tarjan就是dfs的复杂度
O(p+r)
- 判断是否双连通复杂度
O(p)
- 时间复杂度
O(qs(2p+r))上限小于
1×105,稳妥
- 需要注意这种做法一定要多做测试!!!
其他
- 前两次作业的此处省略,没必要写的也省略
- 如有错误还请指正
转载自blog.csdn.net/ourfutr2330/article/details/106118364