[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 ...
随机推荐
- Beta No.5
今天遇到的困难: 前端大部分代码由我们放逐的组员完成,这影响到了我们解决"Fragment碎片刷新时总产生的固定位置"的进程,很难找到源码对应 新加入的成员对界面代码不熟悉. 我们 ...
- Beta冲刺NO.1
Beta冲刺 第一天 1. 昨天的困难 由于今天还是第一天,所以暂时没有昨天的困难. 2. 今天解决的进度 潘伟靖: 对代码进行了review 1.将某些硬编码改为软编码 2.合并了一些方法,简化代码 ...
- 数据结构基础——指针及动态内存分配(malloc)
一.指针 C语言中的指针是一种数据类型,比如说我们用int *a;就定义了一个指针a,它指向一个int类型的数.但是这个指针是未初始化的,所以,一般的,我们都在创建指针时初始化它,以免出错,在还不吃的 ...
- Swift - 使用导航条和导航条控制器来进行页面切换并传递数据
转自:http://www.hangge.com/blog/cache/detail_586.html
- 洛谷 U10783 名字被和谐了
https://www.luogu.org/problem/show?pid=U10783 题目背景 众所周知,我们称g是a的约数,当且仅当g是正数且a mod g = 0. 众所周知,若g既是a的约 ...
- 数据结构与算法 —— 链表linked list(02)
我们继续来看链表的第二道题,来自于leetcode: 两数相加 给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了 ...
- 【深度学习】深入理解Batch Normalization批标准化
这几天面试经常被问到BN层的原理,虽然回答上来了,但还是感觉答得不是很好,今天仔细研究了一下Batch Normalization的原理,以下为参考网上几篇文章总结得出. Batch Normaliz ...
- Oracle银行存取钱系统
Oracle银行存取钱系统 /* 银行系统 要求: 1.创建一个用户信息表(userinfo).一个交易信息表(deal) 2.用户信息表字段:用户编号.用户名称.密码.余额 交易信息表字段:编号.交 ...
- Python内置函数(34)——filter
英文文档: filter(function, iterable) Construct an iterator from those elements of iterable for which fun ...
- ssm框架找不到mysql驱动类WARN DriverManagerDataSource:107 - Could not load driverClass com.mysql.jdbc.Driver
找了很久错误,检查了配置文件,和spring配置数据源,都没有发现问题,最后上网查询了下,发现是由于配置文件后面有空格. 去除掉配置文件后面的空格就可以正常运行了.