【BZOJ1706】relays 奶牛接力跑
程序员文章站
2022-05-22 11:41:09
...
题目:BZOJ1706
解析:
矩阵快速幂。
首先将起点终点离散化降至以内。
考虑最裸的状态转移,令表示经过条边从到的最短路长度,就有:
这样直接转移复杂度是的考虑去掉部分后实际上就是一个矩阵乘法,那么相当于是求初始矩阵的次方,矩阵快速幂即可。
代码:
#include <bits/stdc++.h>
using namespace std;
const int Max=105;
int n,m,s,t,k,rev[Max*10];
struct matrix{int a[Max][Max];}ans,v;
inline matrix mul(const matrix&a,const matrix&b)
{
matrix c;
memset(c.a,0x3f,sizeof(c.a));
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
c.a[i][j]=min(c.a[i][j],a.a[i][k]+b.a[k][j]);
return c;
}
inline void solve()
{
while(k)
{
if(k&1) ans=mul(ans,v);
k>>=1,v=mul(v,v);
}
}
int main()
{
memset(v.a,0x3f,sizeof(v.a));
memset(ans.a,0x3f,sizeof(ans.a));
scanf("%d%d%d%d",&k,&m,&s,&t);
for(int i=1,a,b,c;i<=m;i++)
{
scanf("%d%d%d",&c,&a,&b);
if(!rev[a]) rev[a]=++n;
if(!rev[b]) rev[b]=++n;
v.a[rev[a]][rev[b]]=v.a[rev[b]][rev[a]]=min(v.a[rev[b]][rev[a]],c);
}
for(int i=1;i<=n;i++) ans.a[i][i]=0;
solve();
printf("%d",ans.a[rev[s]][rev[t]]);
return 0;
}
推荐阅读
-
bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑(倍增floyd)
-
【bzoj 1706】relays 奶牛接力跑(Floyd+快速幂)
-
bzoj1706 [usaco2007 Nov]relays 奶牛接力跑 矩阵乘法(倍增floyd)
-
2018.11.09 bzoj1706: relays 奶牛接力跑(倍增+floyd)
-
【bzoj1706】[usaco2007 Nov]relays 奶牛接力跑 离散化+倍增Floyd
-
BZOJ 1706: [usaco2007 Nov]relays 奶牛接力跑 倍增Floyd
-
【BZOJ1706】relays 奶牛接力跑
-
2018.11.09【BZOJ1706】relays 奶牛接力跑(矩阵快速幂优化DP)
-
BZOJ[1706][usaco2007 Nov]relays 奶牛接力跑 倍增Floyd
-
2018.11.09【BZOJ1706】relays 奶牛接力跑(矩阵快速幂优化DP)