题意:求s到e经过k条边的最短路径。
思路:floyd。注意对角线不可以赋初值为0,这里代表的是一条边的边长。
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 205;
const int maxm = 105;
int n;
struct matrix{
int a[maxn][maxn];
matrix operator*( const matrix& b ){
matrix res;
memset( res.a,0x7f,sizeof(res.a) );
for( int i = 1; i <= n;i++ ){
for( int j = 1;j <= n;j++ ){
for( int k = 1;k <= n;k++ ){
res.a[i][j] = min( (LL)res.a[i][j],(LL)a[i][k]+b.a[k][j] );
}
}
}
return res;
}
};
template <typename T>
T mpow( T a,int b ){
T res =a;b--;
while(b){
if(b&1) res = res*a;
b >>=1;
a = a*a;
}
return res;
}
int a[maxn][maxn];
int u[maxm],v[maxm],c[maxm];
vector<int> ve;
void discrete(){
sort(ve.begin(),ve.end());
ve.erase( unique(ve.begin(),ve.end()),ve.end() );
}
int h( int x ){
return lower_bound( ve.begin(),ve.end(),x ) - ve.begin() + 1;
}
int main(){
int b,t,s,e;
while(4 == scanf("%d%d%d%d",&b,&t,&s,&e)) {
int x, y, z;
memset(a, 0x7f, sizeof(a));
for (int i = 1; i <= t; i++) {
scanf("%d%d%d", &z, &x, &y);
ve.push_back(x);
ve.push_back(y);
u[i] = x;
v[i] = y;
c[i] = z;
}
discrete();
for (int i = 1; i <= t; i++) {
int x = h(u[i]), y = h(v[i]), z = c[i];
a[x][y] = a[y][x] = z;
}
n = ve.size();
matrix base;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
base.a[i][j] = a[i][j];
}
}
matrix ans = mpow(base, b);
int xx = h(s), yy = h(e);
printf("%d\n", ans.a[xx][yy]);
}
return 0;
}