标签:总结 main mem pow eof str esc 次方 win
给定一张由T条边构成的无向图,点的编号为1~1000之间的整数。
求从起点S到终点E恰好经过N条边(可以重复经过)的最短路。
第1行:包含四个整数N,T,S,E。
第2..T+1行:每行包含三个整数,描述一条边的边长以及构成边的两个点的编号。
2 6 6 4 11 4 6 4 4 8 8 4 9 6 6 8 2 6 9 3 8 9
10
10
总结:进行N次运算,一次运算的定义是枚举中转点进行松弛操作,运算的实现用矩阵乘法的运算法则和Floyd的思想实现。
代码细节:原图时(i, i)不能置为0。因为我可以问你从1点到1点经过5条道路的最短路是多少(显然不是0
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 205
using namespace std;
struct A
{
int m[N][N];
A() {memset(m, 0x3f, sizeof(m));}
} a;
struct E {int u, v, w;} e[N];
int k, m, sta, en, n;
int b[N], f[1000005];
A mul(A x, A y)
{
A z;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
for(int k = 1; k <= n; k++)
z.m[i][j] = min(z.m[i][j], x.m[i][k] + y.m[k][j]);
return z;
}
A power(A a, int b)
{
A r = a, base = a;
while(b)
{
if(b & 1) r = mul(r, base);
base = mul(base, base);
b >>= 1;
}
return r;
}
int main()
{
cin >> k >> m >> sta >> en;
for(int i = 1; i <= m; i++)
{
cin >> e[i].w >> e[i].u >> e[i].v;
if(!f[e[i].u]) f[e[i].u] = ++n;
if(!f[e[i].v]) f[e[i].v] = ++n;
}
for(int i = 1; i <= m; i++)
{
int u = f[e[i].u], v = f[e[i].v];
a.m[u][v] = a.m[v][u] = min(a.m[v][u], e[i].w);
}
a = power(a, k - 1);
cout << a.m[f[sta]][f[en]];
return 0;
}
标签:总结 main mem pow eof str esc 次方 win
原文地址:https://www.cnblogs.com/BigYellowDog/p/11380623.html