并不对劲的[USACO07NOV,洛谷p2886]Cow Relays
题意就是给一张无向有边权的图、起点、终点,求起点到终点经过n条边的最短路。n<=10^6,点的编号<=10^3,边数<=10^2。
这个边数让人不由自主地想到了floyd,然后发现floyd每次相当于加入了一个点(注意,这里的“一次”也是O(点数^3)的,但是在这一次floyd的过程中不会更新结果。)也就是说,第一次floyd求出来了两点之间只走一条边的最短路,第二次求出来了两点之间只走两条边的最短路……,第n次求出来了只走n条边的最短路。这时候就会发现,n遍不在过程中更新答案的floyd后,答案就出来了。
好不容易推到了这一步,发现了n<=10^6的数据范围,想必心中是有些崩溃的。但是邻接矩阵是什么?是矩阵!这样就可以思考用矩阵快速幂的方法。发现floyd的转移时c[i][j] = min { dis[i][k] + dis[k][j] | i,k,j为图中点的编号},和矩阵快速幂的转移有点像,而且转移时也是上一步求出的答案对于最初的邻接矩阵作运算。这时就可以考虑用一些不对劲的方法改造矩阵乘法。
将矩阵快速幂中的乘法改成上面那样的转移方法,就会发现只要求出邻接矩阵^n就好了。
这样就完了?当然不是。
题目中,点的编号<=10^3,直接floyd肯定会时间超限。注意到边数<=10^2,而每条边顶多连两个与之前不同的点,那么出现的不同的点顶多有200个。将点进行离散化就解决了。
还有一些细节,编的时候都能想得到,在这就不多说了。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<cstdlib>
using namespace std;
typedef struct node{
int mat[][];
}Matrix;
Matrix rd,dis;
int n,t,s,e,siz,mc[];
int read(){
int x=,f=;
char ch=getchar();
while(isdigit(ch)== && ch!='-')ch=getchar();
if(ch=='-')f=-;
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
}
Matrix mul(Matrix a,Matrix b){
Matrix c;
memset(c.mat,0x3f,sizeof(c.mat));
for(int k=;k<=siz;k++){
for(int i=;i<=siz;i++){
for(int j=;j<=siz;j++){
c.mat[i][j]=min(c.mat[i][j],a.mat[i][k]+b.mat[k][j]);
}
}
}
return c;
}
void pow(int tim){
while(tim)
{
if(tim&)
rd=mul(rd,dis);
dis=mul(dis,dis);
tim>>=;
} }
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=read(),t=read(),s=read(),e=read();
memset(rd.mat,0x3f,sizeof(rd.mat));
memset(dis.mat,0x3f,sizeof(dis.mat));
memset(mc,-,sizeof(mc));
for(int i=;i<=t;i++){
int w=read(),u=read(),v=read();
if(mc[u]==-)mc[u]=++siz;
if(mc[v]==-)mc[v]=++siz;
u=mc[u],v=mc[v];
dis.mat[v][u]=min(dis.mat[u][v],w);
dis.mat[u][v]=min(dis.mat[u][v],w);
}
for(int i=;i<=siz;i++){
rd.mat[i][i]=;
}
pow(n);
cout<<rd.mat[mc[s]][mc[e]];
return ;
}
并不对劲的矩阵快速幂
并不对劲的[USACO07NOV,洛谷p2886]Cow Relays的更多相关文章
- 洛谷P2886 [USACO07NOV]牛继电器Cow Relays
题意很简单,给一张图,把基本的求起点到终点最短路改成求经过k条边的最短路. 求最短路常用的算法是dijkstra,SPFA,还有floyd. 考虑floyd的过程: c[i][j]=min(c[i][ ...
- 洛谷 P2886 [USACO07NOV]牛继电器Cow Relays
题面 解题思路 ## floyd+矩阵快速幂,跟GhostCai爷打赌用不用离散化,最后完败..GhostCai真是tql ! 有个巧妙的方法就是将节点重新编号,因为与节点无关. 代码 #includ ...
- 洛谷P2886 [USACO07NOV]Cow Relays G (矩阵乘法与路径问题)
本题就是求两点间只经过n条边的最短路径,定义广义的矩阵乘法,就是把普通的矩阵乘法从求和改成了取最小值,把内部相乘改成了相加. 代码包含三个内容:广义矩阵乘法,矩阵快速幂,离散化: 1 #include ...
- [洛谷P2886] 牛继电器Cow Relays
问题描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...
- 洛谷 [P2886] 牛继电器Cow Relays
最短路 + 矩阵快速幂 我们可以改进矩阵快速幂,使得它适合本题 用图的邻接矩阵和快速幂实现 注意 dis[i][i] 不能置为 0 #include <iostream> #include ...
- 洛谷P2886牛继电器
传送门啦 倍增 $ Floyd $ 注意结构体里二维数组不能开到 $ 2000 $ #include <iostream> #include <cstdio> #include ...
- 2021.11.03 P2886 [USACO07NOV]Cow Relays G(矩阵+floyed)
2021.11.03 P2886 [USACO07NOV]Cow Relays G(矩阵+floyed) [P2886 USACO07NOV]Cow Relays G - 洛谷 | 计算机科学教育新生 ...
- P2886 [USACO07NOV]牛继电器Cow Relays
题目描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...
- 洛谷P2879 [USACO07JAN]区间统计Tallest Cow
To 洛谷.2879 区间统计 题目描述 FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. ...
随机推荐
- [luoguP1947] 笨笨当粉刷匠_NOI导刊2011提高(10)(DP)
传送门 f[i][j][k]表示前i行,最后一行前j个,选k次最优解 ntr[i][j][2]表示当前行区间i~j涂0或1所能刷的正确格子 #include <cstdio> #defin ...
- JAVA自定义监听器的示例代码
JAVA用户自定义事件监听完整例子 JAVA用户自定义事件监听完整例子- —sunfruit 很多介绍用户自定义事件都没有例子,或是例子不全,下面写了一个完整的例子,并写入了注释以便参考,完整 ...
- java中filter的用法
filter过滤器主要使用于前台向后台传递数据是的过滤操作.程度很简单就不说明了,直接给几个已经写好的代码: 一.使浏览器不缓存页面的过滤器 Java代码 import javax.servlet ...
- CCF 201712-4 90分
90分,不知道错在哪里了,dijkstra算法,用一个数组的d[i]表示以i点结尾的小路的长度,以i点为中心扩展时,若下一点为k,如果i->k是小路,则 d[j] = d[k]+M[k][j]; ...
- 《TCP/IP详解卷1:协议》——第3章 IP:网际协议(转载)
1.引言 IP是TCP/IP协议族中最核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输.IP提供不可靠. 无连接的数据报传送服务. (1)不可靠 它不能保证IP数据报能成 ...
- Heredoc和Nowdoc
就象heredoc结构类似于双引号字符串,Nowdoc结构是类似于单引号字符串的.Nowdoc结构很象heredoc结构,但是 nowdoc不进行解析操作 . 这种结构很适合用在不需要进行转义的PHP ...
- python学习之 -- 数据序列化
json / pickle 数据序列化 序列化定义:把变量从内存中变成可存储或传输的过程称为序列化.反序列化:把变量内容从序列化的对象重新读到内存里称为反序列胡. 序列化模块之--pickle使用注意 ...
- ACM-ICPC 2018 焦作赛区网络预赛 H、L
https://nanti.jisuanke.com/t/31721 题意 n个位置 有几个限制相邻的三个怎么怎么样,直接从3开始 矩阵快速幂进行递推就可以了 #include <bits/st ...
- Codeforces 559A(计算几何)
A. Gerald's Hexagon time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- springboot使用过程中遇到的问题
一.工具Intellij IDEA 二.基本问题 1.数据库语句 Caused by: java.lang.IllegalStateException: Cannot load driver clas ...