• 题目链接:

    https://www.luogu.org/problemnew/show/P2886

  • Update 6.16

    最近看了下《算法导论》,惊奇地发现在在介绍\(APSP\) \((All Pairs Shortest Path)\)时的第一个方法就是此法,同时在思考题中看到了不少熟悉的问题,看来《算法导论》还是要多看一下

  • 思路:

    看到这题想了很久,想不到比较优的做法,然后看了书上的解法

    感觉太妙了,将图论与矩阵加速递推结合了起来从而轻而易举地解决了这道题,实在是神奇。

    首先我们构建邻接矩阵\(A\),最初\(A[i][j]\)表示从i到j直接相连路径长度(即不经过其他的点),若两点不直接相连或\(i==j\),都设为\(inf\)

    很明显当\(n==0\)时最初的\(A[i][j]\)表示经过\(n\)条边的最短路

    那么\(n!=0\)时呢?假设\(n==1\),那么我们只要将初始A矩阵进行如此运算:

    \(A[i][j]=min_{1<=k<=n,k!=i,j}(A[i][k]+A[k][j])\)

    此时\(A[i][j]\)当然就表示经过\(n\)条边时从\(i\)到\(j\)的最短路

    那么当\(n==k\)时呢?好象我们需\(k\)次上述运算,但是仔细一看它很想我们的矩阵乘法,显然具有结合律 逃),然后矩阵快速幂就好了...

  • 注意:

    1. inf值最好设大一点,在这里卡了好久

    2. 节点数给出来是1000范围,矩阵乘法会超时,但是边数只有200范围,于是对节点编号离散化。

    3. 不知道为什么POJ上用C++会RE,要用G++

  • 代码:

/*C++ 11*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <vector>
#include <map>
#define ll long long
#define ri register int
using namespace std;
const int maxn=255;
const int inf=999999999;//inf值要设大
int tot=0;
struct Mat{
int g[maxn][maxn];
Mat operator ^(const int &k)const{
int c=k;
//Mat ans=Mat(n);
Mat ans=*this;
Mat res=ans;
while(c){
if(c&1)ans=ans*res;
res=res*res;
c=c>>1;
}
return ans;
}
Mat operator *(const Mat &b)const{
Mat ans;
for(ri i=1;i<=tot;i++){
for(ri j=1;j<=tot;j++){
ans.g[i][j]=inf;
}
}
for(ri i=1;i<=tot;i++){
for(ri j=1;j<=tot;j++){
int tmp=ans.g[i][j];
for(ri k=1;k<=tot;k++){
tmp=min(ans.g[i][j],g[i][k]+b.g[k][j]);
}
ans.g[i][j]=tmp;
}
}
return ans;
}
};
int N,t,s,e;
int di[198164],fx[maxn];
Mat a;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;
return ;
}
int main(){
int dis,u,v;
read(N),read(t),read(s),read(e);
for(ri i=1;i<=maxn;i++){
for(ri j=1;j<=maxn;j++)
a.g[i][j]=inf;
}
for(ri i=1;i<=t;i++){
read(dis),read(u),read(v);
if(!di[u])di[u]=++tot,fx[tot]=u;
if(!di[v])di[v]=++tot,fx[tot]=v;
a.g[di[u]][di[v]]=dis;
a.g[di[v]][di[u]]=dis;
}
a=a^(N-1);
printf("%d\n",a.g[di[s]][di[e]]);
return 0;
}

luogu题解 P2886 【牛继电器Cow Relays】-经过K边最短路&矩阵的更多相关文章

  1. [洛谷P2886] 牛继电器Cow Relays

    问题描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...

  2. Luogu 2886 [USACO07NOV]牛继电器Cow Relays

    BZOJ 1706权限题. 倍增$floyd$. 首先这道题有用的点最多只有$200$个,先离散化. 设$f_{p, i, j}$表示经过$2^p$条边从$i$到$j$的最短路,那么有转移$f_{p, ...

  3. 洛谷 [P2886] 牛继电器Cow Relays

    最短路 + 矩阵快速幂 我们可以改进矩阵快速幂,使得它适合本题 用图的邻接矩阵和快速幂实现 注意 dis[i][i] 不能置为 0 #include <iostream> #include ...

  4. POJ 3613 Cow Relays【k边最短路】

    题目链接:http://poj.org/problem?id=3613 题目大意: 给出n头牛,t条有向边,起点以及终点,限制每头牛放在一个点上,(一个点上可以放多头牛),从起点开始进行接力跑到终点, ...

  5. [LUOGU] P2886 [USACO07NOV]牛继电器Cow Relays

    https://www.luogu.org/problemnew/show/P2886 给定无向连通图,求经过k条边,s到t的最短路 Floyd形式的矩阵乘法,同样满足结合律,所以可以进行快速幂. 离 ...

  6. P2886 [USACO07NOV]牛继电器Cow Relays

    题目描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...

  7. 洛谷P2886 [USACO07NOV]牛继电器Cow Relays

    题意很简单,给一张图,把基本的求起点到终点最短路改成求经过k条边的最短路. 求最短路常用的算法是dijkstra,SPFA,还有floyd. 考虑floyd的过程: c[i][j]=min(c[i][ ...

  8. 洛谷 P2886 [USACO07NOV]牛继电器Cow Relays

    题面 解题思路 ## floyd+矩阵快速幂,跟GhostCai爷打赌用不用离散化,最后完败..GhostCai真是tql ! 有个巧妙的方法就是将节点重新编号,因为与节点无关. 代码 #includ ...

  9. [USACO07NOV]牛继电器Cow Relays

    题目描述 给出一张无向连通图,求S到E经过k条边的最短路. 输入输出样例 输入样例#1: 2 6 6 4 11 4 6 4 4 8 8 4 9 6 6 8 2 6 9 3 8 9 输出样例#1: 10 ...

随机推荐

  1. ArcGIS 10.5 tensorflow安装日记

    ArcGIS 10.5 tensorflow安装日记 商务科技合作:向日葵,135-4855__4328,xiexiaokui#qq.com Datetime: 2019年5月27日星期一 Os: w ...

  2. vue-resource在vuecli3中请求headers修改

    this.$resource.delete({ user_code: Cookie.get("empid"), date: date, file_name: file_name } ...

  3. 在主机上如何构建openwrt的编译环境?

    答: 请参考官方文档

  4. android 上下滑动标题栏和状态栏改变颜色实现

    import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; ...

  5. 常用API的注意事项

    判断定义为String类型的s1和s2是否相等 • String s1 = "abc"; • String s2 = "abc"; //常量池中没有这个字符串对 ...

  6. 009-多线程-JUC集合-Queue-LinkedBlockingDeque

    一.概述 LinkedBlockingDeque是双向链表实现的双向并发阻塞队列.该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除):并且,该阻塞队列是支持线 ...

  7. Python之汉诺塔递归运算

    汉诺塔问题是一个经典的问题.汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆 ...

  8. dubbo的负载均衡策略和容错策略

    一.dubbo 负载均衡策略 random loadbalance 默认情况下,dubbo 是 random load balance 随机调用实现负载均衡,可以对 provider 不同实例设置不同 ...

  9. redcon, Redis兼容的服务器框架

    源代码名称:redcon 源代码网址:http://www.github.com/tidwall/redcon redcon源代码文档 redcon源代码下载 Git URL: 复制代码 git:// ...

  10. PPM / PGM / PBM 图像文件格式

    PPM / PGM / PBM 图像文件格式 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:在进行图像压缩后传输,然后解压缩显示的过程中,通常会用到P ...