题意

给出一张无向图,求出恰巧经过n条边的最短路。

题解

考虑先离散化,那么点的个数只会有202个最多。于是复杂度里面就可以有一个\(n^3\).考虑构造矩阵\(d^1\)表示经过一条边的最短路,那么就会是输入进来的边。那么\(d^k\)表示经过k条边的最短路,则有\(d^k[i][j] = min\{d^k[i][j], d^r[i][k] + d^{k-r}[k][j]\}\)

这玩意其实就是个矩阵乘法的拓展,可以说是广义上的矩阵乘法。

然后就可以处理出2^x次方的所有矩阵,然后\(n^3logn\)得到最终矩阵的答案了。这个算法叫做倍增floyd。

#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
#define inf 0x3f3f3f3f
#define il inline namespace io { #define in(a) a = read()
#define out(a) write(a)
#define outn(a) out(a), putchar('\n') #define I_int ll
inline I_int read() {
I_int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
char F[200];
inline void write(I_int x) {
if (x == 0) return (void) (putchar('0'));
I_int tmp = x > 0 ? x : -x;
if (x < 0) putchar('-');
int cnt = 0;
while (tmp > 0) {
F[cnt++] = tmp % 10 + '0';
tmp /= 10;
}
while (cnt > 0) putchar(F[--cnt]);
}
#undef I_int }
using namespace io; using namespace std; #define N 210 int k,m,s,e;
int x[10*N], y[10*N], v[10*N], a[10*N], lim; struct mat {
int m[N][N];
mat() { memset(m, 0x3f, sizeof(m)); }
mat operator * (const mat x) const {
mat c;
for(int k = 1; k <= lim; ++k) {
for(int i = 1; i <= lim; ++i) {
for(int j = 1; j <= lim; ++j) {
c.m[i][j] = min(c.m[i][j], m[i][k] + x.m[k][j]);
}
}
}
return c;
}
}d[30]; int vis[N*50];
int main() {
in(k);in(m);in(s);in(e); int tot = 0;
a[++tot] = s; a[++tot] = e;
for(int i = 1; i <= m; ++i) {
in(v[i]), in(x[i]), in(y[i]);
a[++tot] = x[i]; a[++tot] = y[i];
}
sort(a+1,a+tot+1);
for(int i = 1; i <= tot; ++i)
if(a[i] != a[i - 1]) vis[a[i]] = ++lim;
s = vis[s]; e = vis[e];
for(int i = 1; i <= m; ++i) {
x[i] = vis[x[i]]; y[i] = vis[y[i]];
d[0].m[x[i]][y[i]] = d[0].m[y[i]][x[i]] = v[i];
}
for(int i = 1; (1 << i) <= k; ++i) d[i] = d[i - 1] * d[i - 1];
mat ans;
for(int i = 1; i <= lim; ++i) ans.m[i][i] = 0;
for(int i = 0; (1 << i) <= k; ++i) if((k>>i)&1) ans = ans * d[i];
outn(ans.m[s][e]);
}

【bzoj1706】[usaco2007 Nov]relays 奶牛接力跑的更多相关文章

  1. bzoj1706: [Usaco2007 Nov]relays 奶牛接力跑 (Floyd+新姿势)

    题目大意:有t(t<=100)条无向边连接两点,求s到e刚好经过n(n<=10^7)条路径的最小距离. 第一反应分层图,但是一看n就懵逼了,不会写.看了题解之后才知道可以这么玩... 首先 ...

  2. [bzoj1706] [usaco2007 Nov]relays 奶牛接力跑

    大概是叫倍增Floyd? 显然最多200个点...f[i][j][k]表示从j到k,走2^i步的最小路程.就随便转移了.. 查询的话就是把n二进制位上是1的那些都并起来. #include<cs ...

  3. bzoj1706 [usaco2007 Nov]relays 奶牛接力跑 矩阵快速幂

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1706 题解 换个方法定义矩阵乘法:先加再取 \(\min\). 对于一个 \(n\times ...

  4. 【BZOJ1706】[usaco2007 Nov]relays 奶牛接力跑 矩阵乘法

    [BZOJ1706][usaco2007 Nov]relays 奶牛接力跑 Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项 ...

  5. BZOJ_[usaco2007 Nov]relays 奶牛接力跑_离散化+倍增弗洛伊德

    BZOJ_[usaco2007 Nov]relays 奶牛接力跑_离散化+倍增弗洛伊德 Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们 ...

  6. 【bzoj1706】[usaco2007 Nov]relays 奶牛接力跑 离散化+倍增Floyd

    题目描述 FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力跑的地点 自然是在牧场中现有的T(2 <= T <= 100) ...

  7. BZOJ 1706: [usaco2007 Nov]relays 奶牛接力跑

    Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力跑的地点 自然是在牧场中现有的T(2 <= T < ...

  8. bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑——倍增floyd

    Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力跑的地点 自然是在牧场中现有的T(2 <= T < ...

  9. 【BZOJ】1706: [usaco2007 Nov]relays 奶牛接力跑

    [题意]给定m条边的无向图,起点s,终点t,要求找出s到t恰好经过n条边的最短路径.n<=10^6,m<=100. [算法]floyd+矩阵快速幂 [题解] 先对点离散化,得到点数N. 对 ...

随机推荐

  1. Helter Skelter (扫描线 + 离散化 + 树状数组)

    扫描线:按照其中一个区间的标记为pos,然后左区间标记d为正影响,有区间标记d为负影响,然后根据所有的pos排序.pos从小扫到大,那么对于某一个区间一定会被扫过2次,那么经过2次之后就只剩下中间那一 ...

  2. xpath ,css

    https://docs.scrapy.org/en/latest/intro/tutorial.html xpath @选择属性  .当前目录下选择 //任意路径选择 /bookstore/book ...

  3. 解释器模式 Interpreter

    代码例子 参考 1.解释器模式定义 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 说明:解释器模式设计到文法规则和抽象语法树. 2.解释器模式的结构 ...

  4. MCMC算法深入理解

    MCMC(Markov Chain Monte Carlo),即马尔科夫链蒙特卡洛方法,是以马尔科夫平稳状态作为理论基础,蒙特卡洛方法作为手段的概率序列生成技术. MCMC理论基础 如果转移矩阵为P的 ...

  5. Java的字段初始化规律

    package 代码测试; public class InitializeBlockClass { {field=200;} public int field=100; public Initiali ...

  6. 在Linux 中如何从进程相关的文件描述中恢复数据

    在Linux中误删除了某个文件,但是 ps-ef|grep 文件名 发现某个进程还在使用该文件,那么可以通 过以下方式恢复文件. 例如:创建一个简单文件/tmp/test.txt, 随便向里面写点内容 ...

  7. C/C++编译、链接、运行的基础知识

    0.C/C++从源文件在编译器的作用下先编译成.s的汇编,然后在汇编器的作用下变成.o的可重定向目标文件,然后在链接器的作用下变成可执行文件 1.在项目中设置的编译寻找目录中的.h文件(一般就是inc ...

  8. 怎样从外网访问内网WampServer?

    本地安装了一个WampServer,只能在局域网内访问,怎样从外网也能访问到本地的WampServer呢?本文将介绍具体的实现步骤. 准备工作 安装并启动WampServer 默认安装的WampSer ...

  9. shell中test命令方法详解

    test命令用法.功能:检查文件和比较值 1)判断表达式 if test  (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2                 两个表达式 ...

  10. 4-20mA电流环路发送器入门(转)

    4-20mA电流环路发送器入门 作者:Collin Wells, 德州仪器精密模拟应用工程师 在现代工业控制系统中,4-20 mA电流环路发送器一直是在控制中心和现场传感器/执行器之间进行数据传输最为 ...