洛谷P1730最小密度路径

  题目传送门;

  首先理解题目,究其本质就是一个最短路问题,而且数据范围贼水,用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;
}
蒟蒻写博客不易,如果有误还请大佬们提出
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com
原文地址:https://www.cnblogs.com/cytus/p/7763182.html