【洛谷P1730】最小密度路徑
阿新 • • 發佈:2019-05-06
size ble double spa friend while 初始 sca cpp
題目大意:給定一個 N 個點,M 條邊的有向圖,現有 Q 個詢問,每次詢問 X 到 Y 的最小密度路徑是多少。最小密度路徑的定義是路徑長度除以路徑邊數。
題解:利用矩陣乘法,可以預處理出從 X 到 Y 恰好經過 K 條邊的最短路是多少。對於每次詢問,直接處理處理即可,時間復雜度為 \(O(n^4)\)。
註意:恰好經過 K 條邊的最短路不能將 G[i][i] 初始化成 0,因為邊數有實際意義,若這樣初始化意味著有自環出現。至少經過 K 條邊的同理,也不能這樣初始化。
代碼如下
#include <bits/stdc++.h> using namespace std; const int maxn=55; const int inf=0x3f3f3f3f; int n,m,q; struct mat{ int d[maxn][maxn]; mat(){memset(d,0x3f,sizeof(d));} int *operator[](int i){return d[i];} friend mat operator*(mat &x,mat &y){ mat z; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) z[i][j]=min(z[i][j],x[i][k]+y[k][j]); return z; } }d[maxn]; void read_and_parse(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int x,y,z;scanf("%d%d%d",&x,&y,&z); d[1][x][y]=min(d[1][x][y],z); } } void solve(){ for(int i=2;i<=n;i++)d[i]=d[i-1]*d[1]; scanf("%d",&q); while(q--){ int x,y;scanf("%d%d",&x,&y); bool flag=0;double ans=1e18; for(int i=n;i;i--){ if(d[i][x][y]!=inf){ flag=1; ans=min(ans,(double)d[i][x][y]/(double)i); } } if(flag)printf("%.3lf\n",ans); else puts("OMG!"); } } int main(){ read_and_parse(); solve(); return 0; }
【洛谷P1730】最小密度路徑