题意:给定一个无向图和一个点对(a,b),求从a到b的恰好长度为k的最短路。
思路:对于图的邻接矩阵,做一次add(见代码)操作,元素变成长度为2的最短路,再自身一次就是长度为4的最短路。按照这个思路加上快速幂的思路就OK了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstdlib>
using namespace std;
#define clc(s,t) memset(s,t,sizeof(s))
#define INF 0x3fffffff
#define N 205
struct edge{
int x,y,w;
}e[105];
struct matrix{
int a[N+5][N+5];
}g,res;
int k,m,x,y,s[N],len;
struct matrix add(matrix p,matrix q){
struct matrix ans;
int i,j,k;
for(i = 1;i<=len;i++)
for(j = 1;j<=len;j++){
ans.a[i][j] = INF;
for(k = 1;k<=len;k++)
ans.a[i][j] = min(ans.a[i][j],p.a[i][k]+q.a[k][j]);
}
return ans;
}
void solve(int n){
int f = 0;
while(n){
if(n&1){
if(f==0){
f = 1;
res = g;
}else
res = add(res,g);
}
g = add(g,g);
n>>=1;
}
}
int main(){
int i,j,a,b;
scanf("%d %d %d %d",&k,&m,&x,&y);
for(i = 0;i<m;i++){
scanf("%d %d %d",&e[i].w,&e[i].x,&e[i].y);
s[i*2] = e[i].x;
s[i*2+1] = e[i].y;
}
sort(s,s+m*2);
len = unique(s,s+m*2)-s;
for(i = 1;i<=len;i++)
for(j = 1;j<=len;j++)
g.a[i][j] = res.a[i][j] = INF;
for(i = 0;i<m;i++){
a = lower_bound(s,s+len,e[i].x)-s+1;
b = lower_bound(s,s+len,e[i].y)-s+1;
g.a[a][b] = g.a[b][a] = e[i].w;
}
solve(k);
x = lower_bound(s, s+len, x)-s+1;
y = lower_bound(s, s+len, y)-s+1;
printf("%d\n",res.a[x][y]);
}