给每个点加上边权为0的自环
设
f
[
i
]
[
j
]
[
t
]
f[i][j][t]
f[i][j][t]表示从点i到点j走2^t步的最长路径长度
那么有
f
[
i
]
[
j
]
[
t
]
=
m
a
x
{
f
[
i
]
[
j
]
[
t
−
1
]
,
f
[
i
]
[
k
]
[
t
−
1
]
+
f
[
k
]
[
j
]
[
t
−
1
]
∗
ρ
2
t
}
f[i][j][t] = max\{f[i][j][t-1], f[i][k][t-1]+f[k][j][t-1]*\rho^{2^t}\}
f[i][j][t]=max{f[i][j][t−1],f[i][k][t−1]+f[k][j][t−1]∗ρ2t}
最后需要加上起点的点权*1
四舍五入保留一位小数就乘10然后+0.5再floor一下再除回去就行了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 107;
double f[maxn][maxn][64], rho;
double w[maxn], g[maxn][maxn], ans;
int n, m, v0;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> w[i];
}
cin >> v0 >> rho;
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
for (int k = 0; k < 64; k++) {
f[i][j][k] = 1061109567;
}
for (int i = 1; i <= n; i++)
for (int t = 0; t <= 63; t++)
f[i][i][t] = 0;
for (int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
f[x][y][0] = -w[y]*rho;
}
ans = 1061109567;
double tmp = rho;
for (int t = 1; t <= 63; t++) {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
f[i][j][t] = min(f[i][j][t], f[i][j][t-1]);
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
f[i][j][t] = min(f[i][j][t], f[i][k][t-1]+f[k][j][t-1]*tmp);
}
}
}
tmp *= tmp;
}
for (int i = 1; i <= n; i++) ans = min(ans, f[v0][i][63]);
ans -= w[v0];
printf("%.1lf\n",-floor(ans*10.0+0.5)/10.0);
return 0;
}