[USACO07NOV]牛继电器Cow Relays
题目描述
给出一张无向连通图,求S到E经过k条边的最短路。
输入输出样例
2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9
10
题解:
法1:dp+floyd+倍增
f[i][j][p]为从i到j经过2^p条边
显然f[i][j][p]=min(f[i][k][p-1]+f[k][j][p-1])
如果n不是2的幂也没事,将n进行二进制分解,再用dp转移
ans[x][i]=min(ans[!x][j]+f[i][j][p]) n的二进制第p位为1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,t,s,e,f[][][],ans[][],num[],pos,logn;
int main()
{int i,d,u,v,p,j,k;
cin>>n>>t>>s>>e;
memset(f,/,sizeof(f));
memset(ans,/,sizeof(ans));
for (i=;i<=t;i++)
{
scanf("%d%d%d",&d,&u,&v);
if (!num[u]) num[u]=++pos;
if (!num[v]) num[v]=++pos;
f[num[u]][num[v]][]=f[num[v]][num[u]][]=d;
}
logn=log2(n);
for (p=;p<=logn;p++)
{
for (k=;k<=pos;k++)
{
for (i=;i<=pos;i++)
{
for (j=;j<=pos;j++)
{
f[i][j][p]=min(f[i][j][p],f[i][k][p-]+f[k][j][p-]);
}
}
}
}
t=;p=;
ans[][num[s]]=;
while (n)
{
if (n&)
{
t=!t;
for (i=;i<=pos;i++)
{ans[t][i]=2e9;
for (j=;j<=pos;j++)
{
ans[t][i]=min(ans[t][i],ans[!t][j]+f[i][j][p]);
}
}
}
p++;
n/=;
}
cout<<ans[t][num[e]];
}
法二:矩阵乘法
可知用邻接矩阵表示时,floyd的过程可以视为矩阵运算,且满足交换律
意思就是先求出走1条边的矩阵,再求出找4条边矩阵
等价于先求出走2条边的矩阵,在求出找3条边矩阵
重载矩阵乘法为floyd的过程,做快速幂就行
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,t,s,e,f[][],num[],pos;
struct mat
{
int s[][];
mat()
{int i,j;
for (i=;i<=pos;i++)
for (j=;j<=pos;j++)
s[i][j]=1e9;
}
mat operator*(const mat &x)
{int i,j,k;
mat ans;
for (k=;k<=pos;k++)
{
for (i=;i<=pos;i++)
{
for (j=;j<=pos;j++)
{
ans.s[i][j]=min(ans.s[i][j],s[i][k]+x.s[k][j]);
}
}
}
return ans;
}
}S,T;
int main()
{int i,j,d,u,v;
cin>>n>>t>>s>>e;
for (i=;i<=t;i++)
{
scanf("%d%d%d",&d,&u,&v);
if (!num[u]) num[u]=++pos;
if (!num[v]) num[v]=++pos;
f[num[u]][num[v]]=f[num[v]][num[u]]=d;
}
mat S,T;
for (i=;i<=pos;i++)
for (j=;j<=pos;j++)
if (f[i][j])
S.s[i][j]=T.s[i][j]=f[i][j];
n--;
while (n)
{
if (n&)
{
S=S*T;
}
T=T*T;
n>>=;
}
cout<<S.s[num[s]][num[e]];
}
[USACO07NOV]牛继电器Cow Relays的更多相关文章
- 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][ ...
- Luogu 2886 [USACO07NOV]牛继电器Cow Relays
BZOJ 1706权限题. 倍增$floyd$. 首先这道题有用的点最多只有$200$个,先离散化. 设$f_{p, i, j}$表示经过$2^p$条边从$i$到$j$的最短路,那么有转移$f_{p, ...
- [USACO07NOV]牛继电器Cow Relays (最短路,DP)
题目链接 Solution 非正解 似乎比较蛇啊,先个一个部分分做法,最短路+\(DP\). 在求最短路的堆或者队列中存储元素 \(dis_{i,j}\) 代表 \(i\) 这个节点,走了 \(j\) ...
- [LUOGU] P2886 [USACO07NOV]牛继电器Cow Relays
https://www.luogu.org/problemnew/show/P2886 给定无向连通图,求经过k条边,s到t的最短路 Floyd形式的矩阵乘法,同样满足结合律,所以可以进行快速幂. 离 ...
- [luoguP2886] [USACO07NOV]牛继电器Cow Relays(矩阵)
传送门 矩阵快速幂,本质是floyd 把 * 改成 + 即可 注意初始化 因为只有100条边,所以可以离散化 #include <cstdio> #include <cstring& ...
- 洛谷 P2886 [USACO07NOV]牛继电器Cow Relays
题面 解题思路 ## floyd+矩阵快速幂,跟GhostCai爷打赌用不用离散化,最后完败..GhostCai真是tql ! 有个巧妙的方法就是将节点重新编号,因为与节点无关. 代码 #includ ...
- [洛谷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 ...
随机推荐
- alpha-咸鱼冲刺day3-紫仪
总汇链接 一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 今天把数据库的表给建好了,学长那边把登陆跟注册页面也做好了(纯页面,html5+css的那种) 四,问题困难 日常 ...
- Build to win
UPDATE:看到周筠老师的评论里的链接,那版式真的非常舒服.我想想模仿模仿他的布局来看看,虽然感觉做的也不是太好.另外对博客内容稍作修改. 一.获得小黄衫的感受 很幸运能够获得"领骑衫&q ...
- 冲刺NO.1
Alpha冲刺第一天 站立式会议 项目进展 项目的第一天,主要工作是对项目的开发进行规划,以及将规划的成果转化为燃尽图与博客文章.依据项目需求分析报告与开题报告中已经完成的设计任务和项目规划,我们将系 ...
- 201621123031 《Java程序设计》第6周学习总结
作业06-接口.内部类 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多 ...
- [SDOI2014]旅行
洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...
- JAVA_SE基础——63.String类的常用方法
获取方法int length() 获取字符串的长度char charAt(int index) 获取特定位置的字符 (角标越界)int indexOf(String str) 查找子串第一次出现的索 ...
- webapi 使用Autofac 开发经历
2018/4/6 号 早上五点..被手机震动吵醒. 之后直接打开电脑,打算再加强下我自己的webapi这套东西. 虽然三年的工作经验接触了N多框架和各种风格的开发方式,但是让我自己来搞一套实在不会搞, ...
- django models的点查询/跨表查询/双下划线查询
django models 在日常的编程中,我们需要建立数据库模型 而往往会用到表与表之间的关系,这就比单表取数据要复杂一些 在多表之间发生关系的情形下,我们如何利用models提供的API的特性获得 ...
- php实现单,双向链表,环形链表解决约瑟夫问题
传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季 http://php.itcast.cn 聊天篇: 数学对我们编程来说,重不重要? 看你站在什么样的层次来说. 如果你应用程序开发,对数学要求 ...
- node框架express
见识到原生nodeJs服务器的恶心后,我们来用下简单好用的框架吧~ 服务器无非主要提供接口和静态文件读取,直接上代码: const express = require('express'); cons ...