当前位置: 首页 > >

【bzoj2360】【cstc2011】【幸福路径】【倍增+floyd】

Description

有向图 G有n个顶点 1,? 2, …,? n,点i 的权值为 w(i)。现在有一只蚂蚁,从
给定的起点 v0出发,沿着图 G 的边爬行。开始时,它的体力为 1。每爬过一条
边,它的体力都会下降为原来的 ρ 倍,其中ρ 是一个给定的小于1的正常数。而
蚂蚁爬到某个顶点时的幸福度,是它当时的体力与该点权值的乘积。?
我们把蚂蚁在爬行路径上幸福度的总和记为 H。很显然,对于不同的爬行路
径,H 的值也可能不同。小 Z 对 H 值的最大可能值很感兴趣,你能帮助他计算
吗?注意,蚂蚁爬行的路径长度可能是无穷的。



Input

每一行中两个数之间用一个空格隔开。?
输入文件第一行包含两个正整数 n,? m,分别表示 G 中顶点的个数和边的条
数。?
第二行包含 n个非负实数,依次表示 n个顶点权值 w(1), w(2), …, w(n)。?
第三行包含一个正整数 v0,表示给定的起点。?
第四行包含一个实数 ρ,表示给定的小于 1的正常数。?
接下来 m行,每行两个正整数 x, y,表示是G的一条有向边。可能有
自环,但不会有重边。



Output

仅包含一个实数,即 H值的最大可能值,四舍五入到小数点后一位。



Sample Input

5 5
10.0 8.0 8.0 8.0 15.0
1
0.5
1 2
2 3
3 4
4 2
4 5


Sample Output

18.0

HINT


对于 100%的数据, n ≤ 100, m ≤ 1000, ρ ≤ 1 ? 10^-6

, w(i) ≤ 100 (i = 1, 2, …, n)。


题解:用f[i][j][k]表示从i走到j走2^k步的最大值。


? ? ? ? ? ?则f[i][j][k]=max(f[i][j][k],f[i][p][k-1]+f[p][j][k-1]*p^(2^(k-1));


因为本题对精度要求不是很高,所以倍增上30遍即可得到正确答案。


代码:



#include
#include
#include
#define N 110
using namespace std;
double f[N][N],g[N][N],a[N],t,p,ans;
int n,m,st,x,y;
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%lf",&a[i]);
scanf("%d%lf",&st,&p);
memset(f,-20,sizeof(f));
for (int i=1;i<=m;i++){scanf("%d%d",&x,&y);f[x][y]=a[y];}
t=p;
for (int q=1;q<=30;q+=1,t*=t){
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
g[i][j]=f[i][j];
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
f[i][j]=max(f[i][j],g[i][k]+g[k][j]*t);
}
for (int i=1;i<=n;i++) ans=max(ans,f[st][i]);
printf("%.1lf",ans*p+a[st]);
}







友情链接: year2525网 工作范文网 QS-ISP 138资料网 528200 工作范文网 baothai 表格模版