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; }