洛谷P4308 CTSC2011幸福路径 倍增floyd

给每个点加上边权为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][t1],f[i][k][t1]+f[k][j][t1]ρ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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值