这是什么鬼??????
floyd+矩阵乘法?????
不是很懂你们奶牛,真会玩。
问题是求无向图上两点间经过k条边的最短路。
定义floyd矩阵乘法(我瞎扯的)为A[i][j]=min(B[i][k]+C[k][j])
然后发现这个满足结合律哎。
如果B为经过x条边的答案,C为经过y条边的答案,那么A为经过x+y条边的答案
好神奇
于是就可以直接套矩阵快速幂了。
真是6的不行
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100+5;
int n;
struct matrix{
int a[N][N];
matrix(){memset(a,0x3f,sizeof(a));}
void init(){memset(a,0x3f,sizeof(a));}
void clear(){memset(a,0,sizeof(a));}
void print(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
printf("%d ",a[i][j]);
putchar('\n');
}
}
matrix operator * (const matrix &b)const{
static matrix ans;
ans.init();
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ans.a[i][j]=min(ans.a[i][j],a[i][k]+b.a[k][j]);
return ans;
}
matrix operator ^ (int k)const{
static matrix ans,b;
ans.init();
for(int i=1;i<=n;i++)ans.a[i][i]=0;
memcpy(b.a,a,sizeof(a));
for(;k;k>>=1,b=b*b)if(k&1)ans=ans*b;
return ans;
}
}g;
int idx[1005];
int id(int x){
if(!idx[x])idx[x]=++n;
return idx[x];
}
int main(){
//freopen("a.in","r",stdin);
int s,t,m,k;
scanf("%d%d%d%d",&k,&m,&s,&t);
s=id(s);t=id(t);
while(m--){
int u,v,w;scanf("%d%d%d",&w,&u,&v);
u=id(u);v=id(v);
g.a[u][v]=min(g.a[u][v],w);
g.a[v][u]=min(g.a[v][u],w);
}
g=g^k;
printf("%d\n",g.a[s][t]);
return 0;
}