bzoj 2306: [Ctsc2011]幸福路径

来源:互联网 发布:java语言的执行模式 编辑:程序博客网 时间:2024/06/05 05:39

题意:

有向图 G有n个顶点 1, 2, …, n,点i 的权值为 w(i)。现在有一只蚂蚁,从
给定的起点 v0出发,沿着图 G 的边爬行。开始时,它的体力为 1。每爬过一条边,它的体力都*p,而蚂蚁爬到某个顶点时的幸福度,是它当时的体力与该点权值的乘积。 求最大幸福值。

题解:

因为当体力很小后,对答案就没什么影响力,所以用一个玄学的倍增floyd卡精度就能过。
f[i][j][t]表示i到j走2t步的最大幸福值。
那么有f[i][j][t]=max{f[i][k][t1]+f[k][j][t1]p2t}
然后就过了。
code:

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespace std;const double eps=1e-10;int n,m;double f[110][110],g[110][110];double w[110],p;int main(){    scanf("%d %d",&n,&m);    for(int i=1;i<=n;i++) scanf("%lf",&w[i]);    int st=0;scanf("%d %lf",&st,&p);    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            if(i!=j) f[i][j]=-1e15;    for(int i=1;i<=m;i++)    {        int x,y;scanf("%d %d",&x,&y);        f[x][y]=w[y]*p;    }    for(;p>eps;p*=p)    {        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++) g[i][j]=-1e15;        for(int k=1;k<=n;k++)            for(int i=1;i<=n;i++)                for(int  j=1;j<=n;j++)                    g[i][j]=max(g[i][j],f[i][k]+f[k][j]*p);        memcpy(f,g,sizeof(f));    }    double ans=0;    for(int i=1;i<=n;i++) ans=max(ans,f[st][i]);    printf("%.1lf",ans+w[st]);}