标签:bzoj bzoj2306 倍增floyd floyd
题目大意:给定一张有向图,每个点有权值,蚂蚁从某个节点出发,初始体力值为1,每走一条边体力值*=p,每经过一个点会获得幸福值为点权*体力值,求最大幸福值
令f[i][j][t]为从点i走到点j花2^t步的最大幸福值
那么有f[i][j][t]=max{f[i][k][t-1]+f[k][j][t-1]*p^(2^t)}
迭代多次即可得到答案的近似值
注意蚂蚁可能卡死在某个点不动,因此初始要将邻接矩阵清为-INF,然后每个点连一条边权为0的自环
此外注意下卡死时最后经过的那个点的权值会不会被统计 这里可能会挂
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 110 using namespace std; int n,m,st; double p,ans,a[M],f[M][M],g[M][M]; int main() { int i,j,k,T,x,y; cin>>n>>m; for(i=1;i<=n;i++) scanf("%lf",&a[i]); cin>>st>>p; memset(f,0xc2,sizeof f); for(i=1;i<=n;i++) f[i][i]=0; for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); f[x][y]=a[y]; } double temp=p; for(T=0;T<=70;T++,temp*=temp) { memset(g,0xc2,sizeof g); for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) g[i][j]=max(g[i][j],f[i][k]+f[k][j]*temp); memcpy(f,g,sizeof f); } for(i=1;i<=n;i++) ans=max(ans,f[st][i]); printf("%.1lf\n",ans*p+a[st]); return 0; }
BZOJ 2306 Ctsc2011 幸福路径 倍增Floyd
标签:bzoj bzoj2306 倍增floyd floyd
原文地址:http://blog.csdn.net/popoqqq/article/details/43926365