• 洛谷P1119灾后重建


    题目

    做一个替我们首先要明确一下数据范围,n《=200,说明n^3的算法是可以过得,而且这个题很明显是一个图论题, 所以我们很容易想到这个题可以用folyd, 但是我在做这个题的时候因为没有深刻理解folyd的意义,因此导致调试了好几小时,

    folyd 的思想是dp,我们可以用f[k][i][j]表示ij之间可以通过编号为1...k的节点的最短路径。

    初值f[0][i][j]为原图的邻接矩阵。

    f[k][i][j]可以从f[k-1][i][j]转移来,表示ij不经过k这个节点。
    也可以从f[k-1][i][k]+f[k-1][k][j]转移过来,表示经过k这个点。
    意思即f[k][i][j] = min(f[k-1][i][j] , f[k-1][i][k]+f[k-1][k][j])

    然后你就会发现f最外层一维空间可以省略,因为f[k]只与f[k-1]有关。

    虽然这个算法非常简单,但也需要找点时间理解这个算法,就不会再有这种问题啦。
    因此我们在dp循环的时候可以使用滚动数组,可以节约点空间。
    这时候我们就可以看回原题了,我们可以先想比较暴力点的算法,就是直接采用floyd,不加任何优化,这样会很慢,因此我们可以寻找可以优化的方法,比如题目中的时间是递增的,因此我们每次状态转移的时候并不用每次都从第一个点找,而是可以接着上一次的询问。
    这样题目就一目了然了。
    坑点:他的编号都是从0开始的,且初始化数组的时候不能开太大,否则会爆
    代码:
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <cstdio>
    #define M 550
    using namespace std;
    int n, m, dis[M][M], t[M], now, ha, k;
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
            {
                dis[i][j] = 214748364;
            }
        for(int i = 0; i < n; i++)
            scanf("%d", &t[i]);
        for(int i = 1; i <= m; i++)
        {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            dis[a][b] = c;
            dis[b][a] = c;
        }
        scanf("%d", &ha);
        for(int g = 1; g <= ha; g++)
        {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            for(k = now; k < n; k++)
            {
                if(t[k] > c)
                    break;
                else
                    for(int i = 0; i < n; i++)
                        for(int j = 0; j < n; j++)
                            dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
            }
            now = k++;
            if(dis[a][b] != 214748364 && t[a] <= c && t[b] <= c)
                printf("%d
    ", dis[a][b]);
            else
                printf("-1
    ");
        }
    }
  • 相关阅读:
    orale数据库的SQL查询
    pl/sql 过程 函数(写一个过程,输入部门编号,在控制台打印这个部门的名称,总人数,平均工资(基本工资+奖金))
    游标练习
    oracle 中使用 pl/sql代码块
    oracle 中怎样实现分页和去处重复
    小米的登陆页面
    tomcat建立双向https安全连接
    简单标签处理过程
    java反射机制
    tomcat配置加密的连接器https
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/9612450.html
Copyright © 2020-2023  润新知