[CTSC2011]幸福路径

题目描述

有向图 G有n个顶点 1, 2, …, n,点i 的权值为 w(i)。现在有一只蚂蚁,从 给定的起点 v0出发,沿着图 G 的边爬行。开始时,它的体力为 1。每爬过一条 边,它的体力都会下降为原来的 ρ 倍,其中ρ 是一个给定的小于1的正常数。而 蚂蚁爬到某个顶点时的幸福度,是它当时的体力与该点权值的乘积。

我们把蚂蚁在爬行路径上幸福度的总和记为 H。很显然,对于不同的爬行路 径,H 的值也可能不同。小 Z 对 H 值的最大可能值很感兴趣,你能帮助他计算 吗?注意,蚂蚁爬行的路径长度可能是无穷的。

输入输出格式

输入格式:

每一行中两个数之间用一个空格隔开。

输入文件第一行包含两个正整数 n, m,分别表示 G 中顶点的个数和边的条 数。

第二行包含 n个非负实数,依次表示 n个顶点权值 w(1), w(2), …, w(n)。

第三行包含一个正整数 v0,表示给定的起点。

第四行包含一个实数 ρ,表示给定的小于 1的正常数。

接下来 m行,每行两个正整数 x, y,表示<x, y>是G的一条有向边。可能有自环,但不会有重边。

输出格式:

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

输入输出样例

输入样例#1: 复制
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
输出样例#1: 复制
18.0

说明

对于 100%的数据, n ≤ 100, m ≤ 1000, ρ ≤ 1 – 10^-6, w(i) ≤ 100 (i = 1, 2, …, n)。

因为保留一位小数,且w(i)<=100

所以当$p^k$<1e-4时可无视

也就是说,当边数大于k时就可以忽略不计

k最大为:

$log_{0.999999}1e-4$约等于$10^7$

所以用倍增floyd求最大值

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 double f[26][101][101],w[101],inf=2e18,p,ans;
 8 int n,m,S;
 9 int main()
10 {int i,j,k,t,u,v;
11   cin>>n>>m;
12   for (i=1;i<=n;i++)
13     {
14       scanf("%lf",&w[i]);
15     }
16   cin>>S;
17   for (i=0;i<=25;i++)
18     for (j=1;j<=n;j++)
19       for (k=1;k<=n;k++)
20     f[i][j][k]=-inf;
21   for (i=1;i<=n;i++)
22     f[0][i][i]=0;
23   scanf("%lf",&p);
24   for (i=1;i<=m;i++)
25     {
26       scanf("%d%d",&u,&v);
27       f[0][u][v]=p*w[v];
28     }
29   for (t=1;t<=25;t++)
30     {
31       for (i=1;i<=n;i++)
32     {
33       for (j=1;j<=n;j++)
34         {
35           for (k=1;k<=n;k++)
36         if (f[t-1][i][k]!=-inf&&f[t-1][k][j]!=-inf)
37           f[t][i][j]=max(f[t][i][j],f[t-1][i][k]+f[t-1][k][j]*p);
38         }
39     }
40       p=p*p;
41     }
42   ans=-inf;
43   for (i=1;i<=n;i++)
44     ans=max(ans,f[25][S][i]+w[S]);
45   printf("%.1lf
",ans);
46 }
原文地址:https://www.cnblogs.com/Y-E-T-I/p/8964124.html