题意:给定一个无向图和一个点对(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]); }