luogu题解 P2886 【牛继电器Cow Relays】-经过K边最短路&矩阵
题目链接:
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\)次上述运算,但是仔细一看它很想我们的矩阵乘法,显然具有结合律 逃),然后矩阵快速幂就好了...
注意:
inf值最好设大一点,在这里卡了好久
节点数给出来是1000范围,矩阵乘法会超时,但是边数只有200范围,于是对节点编号离散化。
不知道为什么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边最短路&矩阵的更多相关文章
- [洛谷P2886] 牛继电器Cow Relays
问题描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...
- Luogu 2886 [USACO07NOV]牛继电器Cow Relays
BZOJ 1706权限题. 倍增$floyd$. 首先这道题有用的点最多只有$200$个,先离散化. 设$f_{p, i, j}$表示经过$2^p$条边从$i$到$j$的最短路,那么有转移$f_{p, ...
- 洛谷 [P2886] 牛继电器Cow Relays
最短路 + 矩阵快速幂 我们可以改进矩阵快速幂,使得它适合本题 用图的邻接矩阵和快速幂实现 注意 dis[i][i] 不能置为 0 #include <iostream> #include ...
- POJ 3613 Cow Relays【k边最短路】
题目链接:http://poj.org/problem?id=3613 题目大意: 给出n头牛,t条有向边,起点以及终点,限制每头牛放在一个点上,(一个点上可以放多头牛),从起点开始进行接力跑到终点, ...
- [LUOGU] P2886 [USACO07NOV]牛继电器Cow Relays
https://www.luogu.org/problemnew/show/P2886 给定无向连通图,求经过k条边,s到t的最短路 Floyd形式的矩阵乘法,同样满足结合律,所以可以进行快速幂. 离 ...
- P2886 [USACO07NOV]牛继电器Cow Relays
题目描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...
- 洛谷P2886 [USACO07NOV]牛继电器Cow Relays
题意很简单,给一张图,把基本的求起点到终点最短路改成求经过k条边的最短路. 求最短路常用的算法是dijkstra,SPFA,还有floyd. 考虑floyd的过程: c[i][j]=min(c[i][ ...
- 洛谷 P2886 [USACO07NOV]牛继电器Cow Relays
题面 解题思路 ## floyd+矩阵快速幂,跟GhostCai爷打赌用不用离散化,最后完败..GhostCai真是tql ! 有个巧妙的方法就是将节点重新编号,因为与节点无关. 代码 #includ ...
- [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 ...
随机推荐
- python笔记7 logging模块 hashlib模块 异常处理 datetime模块 shutil模块 xml模块(了解)
logging模块 日志就是记录一些信息,方便查询或者辅助开发 记录文件,显示屏幕 低配日志, 只能写入文件或者屏幕输出 屏幕输出 import logging logging.debug('调试模式 ...
- C# 将文本写入到文件
将字符串数组写入到文件,每个元素为一行 string[] lines = { "First line", "Second line", "Third ...
- [原][OSG][osgEarth]osgEarth例子程序简介
1.osgearth_graticule:生成经纬线. 2.osgearth_annotation:各类标注(点.线.面.模型.文本等). 3.osgearth_city:加载一个城市三维模型,可以浏 ...
- delphi ADOQUery中错误解决方法"无法为更新定位行。一些值可能已在最后...
使用delphi中的ADOQuery控件中自带的,insert ,edit,delete此操作时,有时会出现下面的错误提示,提示错误信息:"无法为更新定位行.一些值可能已在最后一次读取后已更 ...
- iOS-UIScreen,UIFont,UIColor,UIView,UIButton
6.1 UIScreen // 屏幕的宽度 CGFloat screenW = [UIScreen mainScreen].bounds.size.width; 6.2 UIFont + (UIFon ...
- Linux配置代理IP
Linux配置代理IP: vim /etc/profile http_proxy=http://username:password@ip:port/ https_proxy=http://userna ...
- Ubuntu构建LVS+Keepalived高可用负载均衡集群【生产环境部署】
1.环境说明: 系统版本:Ubuntu 14.04 LVS1物理IP:14.17.64.2 初始接管VIP:14.17.64.13 LVS2物理IP:14.17.64.3 初始接管VIP:14 ...
- Unity与Android刘海屏适配
本周学习Unity与Android刘海屏适配 关于刘海屏适配部分 网上有很多教程 这里只是做一下整理 https://blog.csdn.net/xj1009420846/article/detail ...
- 2019强网杯部分misc&web
0x01 前言 前两天菜鸡+x和几个大哥算是正式参加了一次ctf的线上赛,也是第一次参加这种比赛(前一段时间巨佬也给了我们一个西班牙的比赛,不过不算是正式参赛,做题的时候,比赛已经结束了),没想到出师 ...
- 机器学习算法K-NN的一个使用实例:预测一个人是否患有糖尿病 (KNN-Predict whether a person will have diabetes or not )
学习中...不断更新. 在糖尿病人的数据库中有几列是不能为0的 比如葡萄糖 胰岛素 身体指数和皮肤厚度.所以在数据预处理阶段需要对这些列的数据进行替换. remeber we did 12 minus ...