P1730 Floyed 最小密度路径

来源:互联网 发布:美国非农数据公布时间一览表 编辑:程序博客网 时间:2024/04/30 10:09

题目大意:给出一张有N个点M条边的加权有向无环图,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量)。

分析:
数据范围不大,询问比较多,考虑用dp直接算出所有点对的答案.因为 密度=val/R所以考虑f[x][y][R] 为x=>y 经过R条边的最小值 ,ans=f[x][y][R]/R
状态转移为:
f[i][j][R]=f[i][k][R-1]+f[k][j][1]

PS:m<=1000 n<=100 原题好像有点问题,数组要开大一点

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int M=1e3+10,N=105;const double INF=1000000.000;int n,m,Q,f[N][N][M];int main() {    scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)             for(int j=1;j<=m;j++)                for(int R=1;R<=m;R++)                  f[i][j][R]=INF;    for(int a,b,c,i=1;i<=m;i++) {        scanf("%d%d%d",&a,&b,&c);        f[a][b][1]=min(f[a][b][1],c);    }           fo(R,2,m)        fo(k,1,n)            fo(i,1,n)                fo(j,1,n)                     f[i][j][R]=min(f[i][k][R-1]+f[k][j][1],f[i][j][R]);    int Q;    scanf("%d",&Q);    while(Q--) {        int x,y;        scanf("%d%d",&x,&y);        double ans=INF;         for(int R=1;R<=m;R++) {            if(f[x][y][R]<INF&&ans>double(f[x][y][R])/double(R*1.000)) {                    ans=double(f[x][y][R]/double(R*1.000));            }        }        if(ans>=INF) printf("OMG!\n");        else printf("%.3lf\n",ans);    }    return 0;}