【Floyd矩阵乘法】BZOJ1706- [usaco2007 Nov]relays 奶牛接力跑
【题目大意】
给出一张无向图,求出恰巧经过n条边的最短路。
【思路】
首先题目中只有100条边,却给出了10000个点(实际上最多只能有200个),离散化一下。
后面就是Floyd的新姿势,以前看过的集训队论文里面有:D
一开始的邻接矩阵是经过一条边的最短路,把这个邻接矩阵记作f[0]
f[1]=f[0]*f[0]=f[0]^2(这里的乘法是矩阵乘法),就可以表示恰巧经过两条边的啦。
f[2]=f[1]*f[0]=f[0]^3,恰巧表示经过两条边。
……
所以恰巧经过n条边的最短路是f[n-1]=f[0]^n。
矩阵快速幂一下就好啦。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXM=+;
const int MAXN=+;
const ll INF=1e16;
struct node
{
ll dis[MAXM][MAXM]; }f,result,origin;
int id[MAXN],cnt;
int n,t,s,e;
node operator * (node a,node b)
{
node c;
for (int i=;i<=cnt;i++)
for (int j=;j<=cnt;j++) c.dis[i][j]=INF;
for (int k=;k<=cnt;k++)
for (int i=;i<=cnt;i++)
for (int j=;j<=cnt;j++)
c.dis[i][j]=min(c.dis[i][j],a.dis[i][k]+b.dis[k][j]);
return c;
} int getnum(int x)
{
if (id[x]==-)
{
id[x]=++cnt;
return(cnt);
}
else return(id[x]);
} void init()
{
memset(id,-,sizeof(id));
cnt=;
scanf("%d%d%d%d",&n,&t,&s,&e);
memset(f.dis,,sizeof(f.dis));
for (int i=;i<=t;i++)
{
int u,v,w;
scanf("%d%d%d",&w,&u,&v);
u=getnum(u);
v=getnum(v);
f.dis[u][v]=f.dis[v][u]=w;
}
for (int i=;i<=cnt;i++)
for (int j=;j<=cnt;j++) if (!f.dis[i][j]) f.dis[i][j]=INF;
} void solve()
{
int k=n-;
result=f,origin=f;
while (k)
{
if (k&) result=result*origin;
k>>=;
origin=origin*origin;
}
printf("%lld",result.dis[id[s]][id[e]]);
} int main()
{
init();
solve();
return ;
}
【Floyd矩阵乘法】BZOJ1706- [usaco2007 Nov]relays 奶牛接力跑的更多相关文章
- bzoj1706 [usaco2007 Nov]relays 奶牛接力跑 矩阵快速幂
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1706 题解 换个方法定义矩阵乘法:先加再取 \(\min\). 对于一个 \(n\times ...
- bzoj1706: [Usaco2007 Nov]relays 奶牛接力跑 (Floyd+新姿势)
题目大意:有t(t<=100)条无向边连接两点,求s到e刚好经过n(n<=10^7)条路径的最小距离. 第一反应分层图,但是一看n就懵逼了,不会写.看了题解之后才知道可以这么玩... 首先 ...
- [bzoj1706] [usaco2007 Nov]relays 奶牛接力跑
大概是叫倍增Floyd? 显然最多200个点...f[i][j][k]表示从j到k,走2^i步的最小路程.就随便转移了.. 查询的话就是把n二进制位上是1的那些都并起来. #include<cs ...
- 【BZOJ1706】[usaco2007 Nov]relays 奶牛接力跑 矩阵乘法
[BZOJ1706][usaco2007 Nov]relays 奶牛接力跑 Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项 ...
- BZOJ_[usaco2007 Nov]relays 奶牛接力跑_离散化+倍增弗洛伊德
BZOJ_[usaco2007 Nov]relays 奶牛接力跑_离散化+倍增弗洛伊德 Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们 ...
- 【bzoj1706】[usaco2007 Nov]relays 奶牛接力跑 离散化+倍增Floyd
题目描述 FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力跑的地点 自然是在牧场中现有的T(2 <= T <= 100) ...
- bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑——倍增floyd
Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力跑的地点 自然是在牧场中现有的T(2 <= T < ...
- 【bzoj1706】[usaco2007 Nov]relays 奶牛接力跑
题意 给出一张无向图,求出恰巧经过n条边的最短路. 题解 考虑先离散化,那么点的个数只会有202个最多.于是复杂度里面就可以有一个\(n^3\).考虑构造矩阵\(d^1\)表示经过一条边的最短路,那么 ...
- 【BZOJ】1706: [usaco2007 Nov]relays 奶牛接力跑
[题意]给定m条边的无向图,起点s,终点t,要求找出s到t恰好经过n条边的最短路径.n<=10^6,m<=100. [算法]floyd+矩阵快速幂 [题解] 先对点离散化,得到点数N. 对 ...
随机推荐
- 升级lamp中php5.6到php7.0过程
升级过程我就直接摘录博友,http://www.tangshuang.net/1765.html,几乎问题和解决办法都是参照他的,所以我也就不另外写了.谢谢!! 周末看了一下php7的一些情况,被其强 ...
- 自动检测SOCKET链接断开
如何判断SOCKET已经断开 最近在做一个服务器端程序,C/S结构.功能方面比较简单就是client端与server端建立连接,然后发送消息给server.我在server端会使用专门的线程处理一条s ...
- select()函数用法三之poll函数
poll是Linux中的字符设备驱动中有一个函数,Linux 2.5.44版本后被epoll取代,作用是把当前的文件指针挂到等待队列,和select实现功能差不多. poll()函数:这个函数是某些U ...
- 利用vw+rem实现移动web适配布局
基本概念 1.单位 Px(CSS pixels) 像素 (px) 是一种绝对单位(absolute units), 因为无论其他相关的设置怎么变化,像素指定的值是不会变化的 其实是相对于某个设备而言的 ...
- Fiddler 4 抓包(APP HTTPS )
一.手机连接Fiddler 1.配置fiddler 1.安装fiddler,基本下一步下一步即可: 2.打开fiddler,点击顶部栏Tools——>Options 3.在HTTPS页签勾选“D ...
- 洛谷P1195口袋的天空
传送门啦 一个裸的最小生成树,输出 $ No Answer $ 的情况只有 $ k < n $ 的时候. 开始令 $ num =n $ ,如果 $ num = k $ ,直接输出 $ 0 $ , ...
- opencv(2)绘图
绘制直线 函数为:cv2.line(img,Point pt1,Point pt2,color,thickness=1,line_type=8 shift=0) 有值的代表有默认值,不用给也行.可以看 ...
- POJ 3280 Cheapest Palindrome(区间DP求改成回文串的最小花费)
题目链接:http://poj.org/problem?id=3280 题目大意:给你一个字符串,你可以删除或者增加任意字符,对应有相应的花费,让你通过这些操作使得字符串变为回文串,求最小花费.解题思 ...
- redis主从,哨兵(windows版)
一.下载 由于redis官方并不支持windows操作系统,所以官网上是下不到的,需要到gitlab上下载,下载地址如下: https://github.com/MicrosoftArchive/re ...
- 用戶登陸。防SQL注入,驗證碼不區分大小寫。。
if (string.Compare(TBCheckCode.Text, Session["CheckCodeI"].ToString(), true) == 0) ...