这道题用倍增+floyd。
令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)}
在实际处理时可以省略t,每次floyd只需将p乘方即可。
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=105;
int n,m,st,x,y;
double w[N],p,f[N][N],g[N][N],ans;
int main()
{
register int i,j,k;
scanf("%d %d",&n,&m);
for (i=1;i<=n;i++)
{
scanf("%lf",&w[i]);
}
scanf("%d %lf",&st,&p);
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++) f[i][j]=-1e100;
f[i][i]=0;
}
for (i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
f[x][y]=w[y];
}
double t=p;
for (;p>1e-8;p*=p)
{
for (i=1;i<=n;i++)
for (j=1;j<=n;j++) g[i][j]=-1e100;
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]*p);
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++) f[i][j]=g[i][j];
}
for (i=1;i<=n;i++)
{
ans=max(ans,g[st][i]);
}
printf("%.1lf",w[st]+ans*t);
return 0;
}