連接: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(){;}