• bzoj2306 幸福路径 倍增 Floyd


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

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

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

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

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

     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
    ",ans+a[s]);
    33 }
    34 int sb=haha();
    35 int main(){;}
    bzoj2306
  • 相关阅读:
    ssd笔记
    深度学习 参数笔记
    NVIDIA驱动安装
    下载大文件笔记
    vue中使用echart笔记
    torch.no_grad
    暑期第二周总结
    暑期第一周总结
    第十六周学习进度
    期末总结
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7780565.html
Copyright © 2020-2023  润新知