首先理解题目,究其本质就是一个最短路问题,而且数据范围贼水,用floyd完全没问题,但是题目有变化,要求出路径边权值与边数之比,这里就可以考虑在把floyd中的二维数组变为三维,f[ i ][ j ][ l ]表示从 i 到 j 经过 l 条边的情况,而且因为是有向图,所以从一点到达另一点经过的边数最多为n-1条(除非数据有问题),做完floyd之后就从1~n-1枚举边数,然后比较得出ans即可,不过要注意,对于f[ s ][ t ][ l ],某些 l 的情况是不存在的,所以别忘了赋inf初值。下面是代码:
#include<bits/stdc++.h> #define inf 1e9 using namespace std; int n,m,q; int dis[60][60][1010]; int main() { //freopen("path.in","r",stdin); //freopen("path.out","w",stdout); scanf("%d%d",&n,&m); for(int l=1;l<=m;l++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j][l]=inf; for(int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); if(dis[x][y][1]>z) dis[x][y][1]=z; } for(int l=2;l<=m;l++) for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j][l]=min(dis[i][j][l],dis[i][k][l-1]+dis[k][j][1]); scanf("%d",&q); while(q--){ int x,y; double ans=inf,now=inf; scanf("%d%d",&x,&y); for(int l=1;l<=n;l++) { if(dis[x][y][l]<inf) now=(double)dis[x][y][l]/(double)l; ans=min(ans,now); } if(ans==inf)printf("OMG! "); else printf("%.3lf ",ans); } return 0; }