P4308 [CTSC2011]幸福路径

这道题看到标签是暴力和倍增,然后看题目并没有觉得能写出来,在下就慌得一批(我太菜了

感觉用lca好像写不出来,就参考了一下popo dalao的代码QAQ

题目大意:给定一张有向图,每个点有权值,蚂蚁从某个节点出发,初始体力值为1,每走一条边体力值=p,每经过一个点会获得幸福值为点权体力值,求最大幸福值

这里的 f[t][i][j] 为从点i走到点j花2^t步的最大幸福值

然后就可以得出 *f[t][i][j] = max(f[t][i][j],f[t - 1][i][k] + f[t - 1][k][j] p);**

循环多次就可以得出近似值

蚂蚁可能在某个点保持不动,因此初始要将邻接矩阵清为-inf,然后每个点连一条边权为0的自环

此外注意下卡死时最后经过的那个点的权值会不会被统计 有可能出锅QAQ

代码就十分的简洁

#include<cstdio>
#include<iostream>
#include<cstring>
#define maxn 110
#define inf 999999999.0
using namespace std;
int n, m, x ,y, b;
double a[maxn], p, f[40][maxn][maxn];
int main() {
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++)
        scanf("%lf", &a[i]);
    scanf("%d", &b);
    scanf("%lf", &p);
    for(int t = 0; t <= 35; t++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                f[t][i][j] = -inf;
    for(int i = 0; i <= n; i++)
        f[0][i][i] = 0;
    for(int i = 1; i <= m; i++) {
        scanf("%d %d", &x, &y);
        f[0][x][y] = a[y] * p;
    }
    for(int t = 1; t <= 35; t++) {
        for(int k = 1; k <= n; k++)
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++)
                    f[t][i][j] = max(f[t][i][j],f[t - 1][i][k] + f[t - 1][k][j] * p);
        p *= p;
    }
    double ans = -inf;
    for(int i = 1;i <= n;i++)
    ans = max(ans,f[35][b][i]);
    printf("%.1lf\n", ans + a[b]);
    return 0;
}

 

posted @ 2019-04-04 20:30  机器闵  阅读(109)  评论(0编辑  收藏  举报