最小密度路徑 洛谷p1730
阿新 • • 發佈:2018-12-16
題目描述
給出一張有N個點M條邊的加權有向無環圖,接下來有Q個詢問,每個詢問包括2個節點X和Y,要求算出從X到Y的一條路徑,使得密度最小(密度的定義為,路徑上邊的權值和除以邊的數量)。
輸入輸出格式
輸入格式:
第一行包括2個整數N和M。
以下M行,每行三個數字A、B、W,表示從A到B有一條權值為W的有向邊。
再下一行有一個整數Q。
以下Q行,每行一個詢問X和Y,如題意所訴。
輸出格式:
對於每個詢問輸出一行,表示該詢問的最小密度路徑的密度(保留3位小數),如果不存在這麼一條路徑輸出“OMG!”(不含引號)。
輸入輸出樣例
輸入樣例#1: 複製
3 3 1 3 5 2 1 6 2 3 6 2 1 3 2 3
輸出樣例#1: 複製
5.000 5.500
說明
1 ≤ N ≤ 50,1 ≤ M ≤ 1000,1 ≤ W ≤ 100000,1 ≤ Q ≤ 100000
f[i][j][h]=min(f[i][[k][1]+f[k][j][h-1]),表示從i到j經過h條路徑的最短路,轉移時列舉斷點k,強制使k表示路徑上離i最近的點。
#include<bits/stdc++.h> #define f(i,l,r) for(i=(l);i<=(r);i++) using namespace std; const int MAXN=55,INF=1000000000; int dis[MAXN][MAXN][1005]; int n,m,Q; int main() { ios::sync_with_stdio(false); int i,j,k,u,v,w,t,tt; memset(dis,60,sizeof(dis)); cin>>n>>m; f(i,1,m){ cin>>u>>v>>w; dis[u][v][1]=min(dis[u][v][1],w); } f(t,2,m){ f(k,1,n){ f(i,1,n){ f(j,1,n){ if(dis[i][k][1]>INF||dis[k][j][t-1]>INF) continue; dis[i][j][t]=min(dis[i][j][t],dis[i][k][1]+dis[k][j][t-1]); } } } } cin>>Q; f(i,1,Q){ cin>>u>>v; double ans=INF; f(j,1,m){ if(dis[u][v][j]>INF) continue; ans=min(ans,1.0*dis[u][v][j]/j); } if(ans==INF) cout<<"OMG!"<<endl; else cout<<fixed<<setprecision(3)<<ans<<endl; } return 0; }