链接
题目描述
给出一个无向图,起点s ,终点e ,t 条边和一个正整数n ,求从 s 到 e 走过 n 条边的最短路径长度。
思路
把乘法那段修改成取最小值(类似于floyd
然后直接跑矩阵乘法
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n, t, s, e, numm, num[1000005];
struct matrix
{
int a[105][105];
}g, Ans;
matrix operator *(matrix a, matrix b)
{
matrix c;
memset(c.a, 0x3f3f3f3f, sizeof(c.a));
for(int k = 1; k <= numm; ++k)
for(int i = 1; i <= numm; ++i)
for(int j = 1; j <= numm; ++j)
c.a[i][j] = min(c.a[i][j], a.a[i][k] + b.a[k][j]);
return c;
}
void quick_pow(int t)
{
t--;
Ans = g;
while(t)
{
if(t & 1) Ans = Ans * g;
g = g * g;
t >>= 1;
}
}
int main()
{
memset(g.a, 0x3f3f3f3f, sizeof(g.a));
scanf("%d%d%d%d", &n, &t, &s, &e);
for(int i = 1; i <= t; ++i)
{
int u, v, w;
scanf("%d%d%d", &w, &u, &v);
if(!num[u]) num[u] = ++numm;
if(!num[v]) num[v] = ++numm;
g.a[num[u]][num[v]] = g.a[num[v]][num[u]] = w;
}
quick_pow(n);
printf("%d", Ans.a[num[s]][num[e]]);
return 0;
}