https://www.luogu.org/problem/P2886
题目描述:
给出一张无向连通图,求\(S\)到\(E\)经过\(k\)条边的最短路。
对于一类\(S\)到\(E\)走指定数量的边数,求它的最短路或条数,都可以采用矩阵快速幂的方式解决.我们回忆一下那一个慢得惊人的\(floyd\)算法,将它的\(dp\)方程式提取出来.
\(floyd[i][j]=min(floyd[i][k]+floyd[k][j])\)
如果我们把\(floyd\)看做一个矩阵,那么矩阵乘法的标准式则为:
\(floyd[i][j]=\sum_{i=1}^{n}(floyd[i][k]×floyd[k][j])\)
我们可以寻找这个方程的本质,可以发现,\((i,j)\)的路径条数可以利用加乘原理,化为\((i,k)×(k,j)\)的和,我们可以考虑这两个\(dp\)方程有什么相似之处.可以发现,上面的那个\(dp\)方程也可以用矩阵乘法的式子替代.我们可以将上面的\(dp\)式定义为矩阵\(min\).现在我们可以考虑k的存在,走\(k\)条边的状态可以由a条边的状态与\(k-a\)条边的状态转移过来,如果我们将走k条边的状态看做一个矩阵,则\(k\)条边的状态可以正好看做\(k\)个\(1\)矩阵相乘,并用矩阵快速“\(min\)"加速.矩阵\(min\)易证是满足结合律的.
原问题便转化为了求一个矩阵的\(k\)次"\(min\)".现在我们来考虑初始状态:当\(k\)=1时,就为邻接矩阵.
注意:矩阵“\(min\)"没有单位元.
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int map[201][201];
};
struct lisan
{
int num,data,newdata;
bool operator < (const lisan &a)const
{
return num<a.num;
}
};
bool cmp(lisan a,lisan b)
{
return a.data<b.data;
}
lisan l[301];
int n,t,s,e,edges[301][3],len,map[1001];
node now,c,res;
node mul(node a,node b)
{
for (int i=1;i<=200;++i)
for (int j=1;j<=200;++j)
c.map[i][j]=1e9;
for (int i=1;i<=200;++i)
for (int j=1;j<=200;++j)
for (int k=1;k<=200;++k)
c.map[i][j]=min(c.map[i][j],a.map[i][k]+b.map[k][j]);
return c;
}
node fast_pow(node a,int b)
{
if (b==1)
return a;
if (b&1)
return mul(fast_pow(mul(a,a),b/2),a);
else
return fast_pow(mul(a,a),b/2);
}
int main()
{
int useless=0;
cin>>n>>t>>s>>e;
for (int i=1;i<=200;++i)
for (int j=1;j<=200;++j)
now.map[i][j]=(1e9);
for (int i=1;i<=t;++i)
{
cin>>edges[i][2]>>edges[i][0]>>edges[i][1];
l[++len].data=edges[i][0];
l[len].num=len;
l[++len].data=edges[i][1];
l[len].num=len;
}
sort(l+1,l+len+1,cmp);
for (int i=1;i<=len;++i)
{
l[i].newdata=i-useless;
map[l[i].data]=l[i].newdata;
if (l[i].data==l[i+1].data)
useless++;
}
sort(l+1,l+len+1);
for (int i=1;i<=t;++i)
now.map[l[i*2-1].newdata][l[i*2].newdata]=now.map[l[i*2].newdata][l[i*2-1].newdata]=min(now.map[l[i*2-1].newdata][l[i*2].newdata],edges[i][2]);
res=fast_pow(now,n);
cout<<res.map[map[s]][map[e]]<<endl;
return 0;
}
标签:Cow,USACO07NOV,edges,min,矩阵,len,floyd,条边,Relays
From: https://www.cnblogs.com/zhouhuanyi/p/16983568.html