• [洛谷P1730] 最小密度路径


    类型:Floyd

    传送门:>Here<

    题意:定义一条路径密度 = 该路径长度 / 边数。给出一张$DAG$,现有$Q$次询问,每次给出$X,Y$,问$X,Y$的最小密度路径($N leq 50$)

    解题思路

    由于$N$非常小,考虑$Floyd$求最短路。但是这题与$Floyd$的不同就在于需要除以边数

    可以枚举边的数量。在边的数量$k$确定时,只需要求得恰好经过$k$条边的最短路即可。有没有联想到矩阵乘法……但是这道题是要求先预处理之后询问,因此矩阵乘法的$log M$优化就没有意义了,因为不管怎样$M$条边的最短路都要求出来

    $f[i][j][k]$表示路径$(i,j)$恰好经过$k$条边的最短路。于是我们易得$$f[i][j][k]=Min{ f[i][p][k-g]+f[p][j][g] }$$其中$p$枚举中介点,$g$枚举边数的中介点,$i,j,k$都要扫,于是复杂度$O(n^5)$……

    考虑省去一层循环。我们发现刚才的推法会有很多重复的情况,事实上既然已经枚举了中介点$p$,枚举$g$就没有意义了。我们就当$g=1$,因为$g eq 1$的情况一定会归属于$p$为其他节点时的情况。因此$$f[i][j][k]=Min{ f[i][p][k-1]+f[p][j][1] }$$

    Code

    会有重边,所以邻接矩阵赋值时要打最小值

    /*By DennyQi 2018.8.16*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b)) ? (a) : (b))
    #define  Min(a,b)  (((a)<(b)) ? (a) : (b))
    using namespace std;
    typedef long long ll;
    const int MAXN = 10010;
    const int MAXM = 27010;
    const int INF = 1061109567;
    inline int read(){
        int x = 0; int w = 1; register int c = getchar();
        while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') w = -1, c = getchar();
        while(c >= '0' && c <= '9') x = (x<<3) + (x<<1) + c - '0', c = getchar();return x * w;
    }
    int N,M,Q,x,y,z;
    int f[55][55][1010];
    int main(){
        memset(f, 0x3f, sizeof(f));
        N=r,M=r;
        for(int i = 1; i <= M; ++i){
            x=r,y=r,z=r;
            f[x][y][1]=Min(f[x][y][1],z);
        }
        for(int g = 2; g <= M; ++g)
            for(int k = 1; k <= N; ++k)
                for(int i = 1; i <= N; ++i)
                    for(int j = 1; j <= N; ++j)
                        f[i][j][g] = Min(f[i][j][g], f[i][k][g-1] + f[k][j][1]);
        Q=r; 
        while(Q--){
            double cur,ans = 9999999.99; bool flg = 0;
            x=r, y=r;
            for(int k = 1; k <= M; ++k){
                if(f[x][y][k] != INF) flg = 1;
                cur = (double)f[x][y][k] / (double)k;
                ans = Min(ans, cur);
            }
            if(!flg){ printf("OMG!
    "); continue; }
            printf("%.3f
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    shell color
    mac os develop
    git 实用命令
    FlexSlider插件的详细设置参数 http://www.woothemes.com/flexslider/
    å∫ç∂´ƒ©˙ˆ∆˚¬µ˜øπœ®ß†¨√∑≈¥Ω who know?
    apple mac 下使用机械键盘的办法,键盘映射工具软件,apple mac Mechanical keyboard
    地图比例尺与高德地图中的缩放级别(0-20)的映射关系与转换方法
    【转】ViewPager 一屏显示多个子页面
    Android中解析XML格式数据的方法
    Linux 中的 Service
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9488734.html
Copyright © 2020-2023  润新知