【做题】HDU6331 Walking Plan——矩阵&分块
题意:给出一个有\(n\)个结点的有向图,边有边权。有\(q\)组询问,每次给出\(s,t,k\),问从\(s\)到\(t\)至少经过\(k\)条边的最短路。
\(n \leq 50, \, q \leq 10^5, \, k \leq 10^4\)
首先,注意到\(n\)非常小这个性质。对于很多这类点数少,询问不易维护也不复杂的图论题,可以用矩阵来做。
我们设原图的邻接矩阵为\(G\),并定义矩阵的二元运算\(\bigotimes\)为:
\]
那么,令\(A^k = \underbrace{A \bigotimes A \cdots A}_{k\text{ times}}\),那么\((G^k)_{ij}\)就等于从\(i\)到\(j\)恰好走\(k\)步的最短路。因此,每次询问的答案就是\(G^k \bigotimes S\),其中\(S\)为图floyd后得到的邻接矩阵。
接下来,让我们考虑这样一个暴力:一开始对于所有可能的路径长度\(l \space (l \leq k + n )\),求出\(G^l \bigotimes S\)。这样预处理是\(O(n^3 k)\),询问是\(O(1)\)。
这样做的话,预处理复杂过高,但每次询问能允许更高的复杂度(\(O(n)\))。注意到,询问要求的只是一个矩阵上的一个元素的罢了。因此,如果我们能把所有\(G^k \bigotimes S\)都表示为\(A \bigotimes B\)的形式,并且所有可能的\(A\)和\(B\)的总数量可以接受,就可以了。这也相当于把所有\(k\)拆分为两个数。
答案是分块。令块大小为\(H(k)\),那么我们可以把\(k\)分为\(\left\lfloor \frac {k} {H(k)} \right\rfloor \times H(k) + k \mod H(k)\)的形式。因此,我们令\(H(k) = \sqrt k\),那么,只要求出所有\(A_i = G^{i\sqrt k}, \ B_i = G_i \bigotimes S\),就可以\(O(n)\)回答每次询问,且\(|A| = |B| = \sqrt k\),故预处理复杂度也能达到\(O(n^3 \sqrt k)\)。
时间复杂度\(O(n^3 \sqrt k + nq)\)。
#include <bits/stdc++.h>
using namespace std;
const int N = 55, BAS = 100, INF = 0x3f3f3f3f;
typedef int mat[N][N];
int n,m,q;
mat a[N * 3],b[N * 3];
void mul(mat& x,mat y,mat z) {
memset(x,0x3f,sizeof(mat));
for (int k = 1 ; k <= n ; ++ k)
for (int i = 1 ; i <= n ; ++ i)
for (int j = 1 ; j <= n ; ++ j)
x[i][j] = min(x[i][j],y[i][k] + z[k][j]);
}
int main() {
int T,x,y,z,ret;
scanf("%d",&T);
while (T --) {
scanf("%d%d",&n,&m);
memset(a,0x3f,sizeof a);
memset(b,0x3f,sizeof b);
for (int i = 1 ; i <= m ; ++ i) {
scanf("%d%d%d",&x,&y,&z);
b[1][x][y] = min(b[1][x][y],z);
}
for (int i = 1 ; i <= n ; ++ i)
a[0][i][i] = 0, b[0][i][i] = 0;
for (int i = 2 ; i <= BAS + n ; ++ i)
mul(b[i],b[i-1],b[1]);
for (int i = 1 ; i <= n ; ++ i)
for (int j = 1 ; j <= n ; ++ j)
a[1][i][j] = b[100][i][j];
for (int i = 2 ; i <= BAS ; ++ i)
mul(a[i],a[i-1],a[1]);
for (int k = BAS + n - 1 ; k >= 0 ; -- k)
for (int i = 1 ; i <= n ; ++ i)
for (int j = 1 ; j <= n ; ++ j)
b[k][i][j] = min(b[k][i][j],b[k+1][i][j]);
scanf("%d",&q);
for (int i = 1 ; i <= q ; ++ i) {
scanf("%d%d%d",&x,&y,&z);
ret = INF;
for (int k = 1 ; k <= n ; ++ k)
ret = min(ret,a[z/BAS][x][k] + b[z%BAS][k][y]);
if (ret != INF) printf("%d\n",ret);
else puts("-1");
}
}
return 0;
}
小结:感觉分块白学了……还是只会死板地使用。
【做题】HDU6331 Walking Plan——矩阵&分块的更多相关文章
- hdu6331 Walking Plan
题意: sol: 考虑floyed 直接暴力做的话复杂度是kn^3会炸. 考虑一个比较神仙的分块做法. 注意到我们是可以直接求单独某个k的矩阵,使用矩阵快速幂即可(取min的矩阵乘法). 单独求一次的 ...
- HDU6331 Problem M. Walking Plan【Floyd + 矩阵 + 分块】
HDU6331 Problem M. Walking Plan 题意: 给出一张有\(N\)个点的有向图,有\(q\)次询问,每次询问从\(s\)到\(t\)且最少走\(k\)条边的最短路径是多少 \ ...
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
- 2018HDU多校训练-3-Problem M. Walking Plan
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6331 Walking Plan Problem Description There are n inte ...
- HDU6331Problem M. Walking Plan
传送门 分块floyd $f[i][j][k]$表示从i走k步到j的最短路 $g[i][j][k]$表示从i走k*100步到j的最短路 $h[i][j][k]$表示从i至少走k步到j的最短路 询问从x ...
- 最小割 总结&&做题记录
模型要点: 1.一般适用于二取一问题或者01规划. 2.利用最小割=最大流,转化为最大流求之. 建议阅读胡伯涛的论文 <<最小割模型在信息学竞赛的应用>>,有精彩有序的证明和各 ...
- project euler做题记录
ProjectEuler_做题记录 简单记录一下. problem 441 The inverse summation of coprime couples 神仙题.考虑答案为: \[\begin{a ...
- AtCoder Grand Contest 11~17 做题小记
原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-11-to-20.html UPD(2018-11-16): ...
- AtCoder Grand Contest 1~10 做题小记
原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-1-to-10.html 考虑到博客内容较多,编辑不方便的情 ...
随机推荐
- PID控制動手玩玩看
PID控制動手玩玩看 PID三個參數到底該怎麼調才好,真的是一門藝術. 雖然在Marlin韌體內有提供自動測量的功能,但是測得的結果,不見得能令人滿意,還是需要調整.可是到底該怎麼調整?從哪個參數開始 ...
- GitHub 代码上传
方法一 登录GitHub后,点击下面的图 New responsitory 按钮 或者点击绿色按钮 New repository,新建一个新建一个远程仓库(remote repository),点击后 ...
- Spark学习之路 (十)SparkCore的调优之Shuffle调优
摘抄自https://tech.meituan.com/spark-tuning-pro.html 一.概述 大多数Spark作业的性能主要就是消耗在了shuffle环节,因为该环节包含了大量的磁盘I ...
- 【Hbase学习之三】Hbase Java API
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-2.6.5 hbase-0.98.12.1-h ...
- org/hibernate/ejb/HibernatePersistence
java.lang.NoClassDefFoundError: org/hibernate/ejb/HibernatePersistence 缺少依赖包:hibernate-entitymanager ...
- spriteJS
https://blog.csdn.net/qq_37261367/article/details/84662028
- mybatis源码解析4---Configuration解析
Configuration类解析 Configuration类位于mybatis包的org.apache.ibatis.session目录下,是mybatis的全局变量,属性就是对应于mybatis的 ...
- 初探AngularJs框架(三)
一.实现todoList的demo 功能很简单,提供一个文本框,用户输入回车后添加新条目.每个条目可以在待处理和处理中两个区域间切换,每个条目都可以被删除,大致的界面如下图所示: 二.处理逻辑 首先将 ...
- centos 文件新建、删除、移动、复制等命令
创建目录 mkdir 文件名 mkdir /var/www/test cp复制命令 cp命令复制文件从一个位置到另一位置.如果目的地文件存在,将覆复写该文件: 如果目的地目录存在,文件将复制到该目录下 ...
- MyBatis中的if写法
<if test="latn_id !=null and latn_id !='' and latn_id !='100'"> and latnid=#{latn_id ...