bzoj2306 幸福路径 倍增 Floyd

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2306

题意:一张有向图,每个点有一个权值w(x)w(x),给出路径起点求出最大f(x)=sigma(w(x)p)f(x)=sigma(w(x)p),其中,pp初始值为11,每走一步这个值都会乘上另一个给出的常量。

由于这个题精度要求极低(只有1e11e1),所以我们直接迭代求值即可。

但是如果我们这么一步一步搞肯定会TT……这时候我们就需要用一些黑科技:倍增。我们每次倍增前进,前进的时候在每一层做一次FloydFloyd,做完之后合并再到下一层。

这样就可以愉快的解决啦~最后不要忘记加上起点时候的权值~

复制代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn=105,maxm=1005;
 7 int n,m;double a[maxn],f[maxn][maxn],g[maxn][maxn];
 8 int haha()
 9 {
10     scanf("%d%d",&n,&m);
11     for(int i=1;i<=n;i++)scanf("%lf",&a[i]);
12     int s;scanf("%d",&s);
13     for(int i=1;i<=n;i++)
14         for(int j=1;j<=n;j++)f[i][j]=i==j?0:-1e100;
15     double p;scanf("%lf",&p);
16     for(int i=1;i<=m;i++)
17     {
18         int x,y;scanf("%d%d",&x,&y);
19         f[x][y]=a[y]*p;
20     }
21     for(;p>1e-10;p*=p)
22     {
23         for(int i=1;i<=n;i++)
24             for(int j=1;j<=n;j++)g[i][j]=-1e100;
25         for(int k=1;k<=n;k++)
26             for(int i=1;i<=n;i++)
27                 for(int j=1;j<=n;j++)g[i][j]=max(g[i][j],f[i][k]+f[k][j]*p);
28         memcpy(f,g,sizeof(g));
29     }
30     double ans=0;
31     for(int i=1;i<=n;i++)ans=max(ans,f[s][i]);
32     printf("%0.1lf\n",ans+a[s]);
33 }
34 int sb=haha();
35 int main(){;}
bzoj2306
复制代码

 

posted @   ccc000111  阅读(328)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示