bzoj2306 幸福路徑 倍增 Floyd

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

題意:一張有向圖,每一個點有一個權值$w(x)$,給出路徑起點求出最大$f(x)=sigma(w(x)*p)$,其中,$p$初始值爲$1$,每走一步這個值都會乘上另外一個給出的常量。ios

因爲這個題精度要求極低(只有$1e-1$),因此咱們直接迭代求值便可。ide

可是若是咱們這麼一步一步搞確定會$T$……這時候咱們就須要用一些黑科技:倍增。咱們每次倍增前進,前進的時候在每一層作一次$Floyd$,作完以後合併再到下一層。spa

這樣就能夠愉快的解決啦~最後不要忘記加上起點時候的權值~code

 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
相關文章
相關標籤/搜索