题意

给出一张无向图,求出恰巧经过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. 《大话设计模式》c++实现 状态模式

    状态模式包含如下角色: Context: 环境类 State: 抽象状态类 ConcreteState: 具体状态类 2)适用场景: a)状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂 ...

  2. date的用法

    date -d "-1 month" "+%T"  当前时间减少一个月 +%T 简便表示时分秒 +%F 简便表示年月日 date +%Y 四位年份 date + ...

  3. 使用js调用js

    直接上源码: <div class="choose"> choose a mode<br> <hr> <button type=" ...

  4. lua学习之循环求一个数的阶乘

    --第3题 利用循环求n的阶乘 --参数检查是否是自然数 function IsNaturalNumber(n) ~= )then return false else return true end ...

  5. 【安装虚拟机三】设置Linux IP地址

    环境 VMware 10 CentOS-6.5-x86_64 第一步:查看IP信息linux:ifconfig (windows:ipconfig) 第二步:编辑网卡信息 vi /etc/syscon ...

  6. python isinstance()方法的使用

    1. 描述Python中的 isinstance() 函数,是Python中的一个内置函数,用来判断一个函数是否是一个已知的类型,类似 type(). 2. 语法isinstance(object,c ...

  7. windows下多个python版本共存,如何在Windows7系统上安装最新的64位Python3.6.2

    windows下多个python版本共存,如何在Windows7系统上安装最新的64位Python3.6.2 1.官网下载python3.6.2https://www.python.org/ftp/p ...

  8. Lucene 个人领悟 (三)

    其实接下来就是贴一下代码,熟悉一下Lucene的正常工作流程,或者说怎么使用这个API,更深层次的东西这篇文章不会讲到. 上一篇文章也说了maven的配置,只要你电脑联网就可以下载下来.我贴一下代码. ...

  9. python shutil模块简单介绍

    python shutil模块简单介绍 简介 shutil模块提供了大量的文件的高级操作.特别针对文件拷贝和删除,主要功能为目录和文件操作以及压缩操作. shutil 模块方法: copy(src, ...

  10. Python爬虫_Selenium与PhantomJS

    Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动化操作,不同是Selenium可以直接运 ...