洛谷 P1119 灾后重建(最短路_Floyd)

本文介绍了一种使用Floyd算法优化处理动态更新的图问题的方法,通过预处理节点间路径来加速后续查询,适用于节点权重非递减场景。

传送门


第一反应是对于每个询问建一次边跑最短路,但似乎会TLE,于是再看一眼题面
t[0] ≤ t[1] ≤ … ≤ t[N – 1]
数据保证了t是不下降的
于是我们可以边输入询问边处理,每次把t[i]<=t且没有处理过的点作为中转站跑一次Floyd,判-1,输出即可。

Code:

#include<cstdio>
#include<cstdlib>
#include<cstring>

const int INF=0x3f3f3f3f;

int a[210][210];
int t[210];
int n,m,q;

int main()
{
    memset(a,INF,sizeof(a));
    memset(t,INF,sizeof(t));
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&t[i]);
        a[i][i]=0;
    }
    for(int i=1;i<=m;i++)
    {
        int x,y,c;
        scanf("%d %d %d",&x,&y,&c);
        x++;y++;
        a[x][y]=a[y][x]=c;
    }
    scanf("%d",&q);
    int k=1;
    for(int i=1;i<=q;i++)
    {
        int sx,sy,sd;
        scanf("%d %d %d",&sx,&sy,&sd);
        sx++;sy++;
        while(t[k]<=sd)
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    if(a[i][k]+a[k][j]<a[i][j]) a[i][j]=a[i][k]+a[k][j];
            k++;
        }
        if(a[sx][sy]>=INF || t[sx]>sd || t[sy]>sd) printf("-1\n");
        else printf("%d\n",a[sx][sy]);
    }
}
下载前必看:https://renmaiwang.cn/s/bvbfw Verilog设计_串并转换 / 移位寄存器实现了一种串并转换的功能,其核心原理在于移位寄存器的运用。 这里详细展示了串转并以及并转串两种不同的设计方案。 每一种转换模式都设有专属的使能信号,同时并行输出数据的格式提供了两种选择:低有效位优先(lsb)和高有效位优先(msb)。 串并转换技术主要应用于串行传输与并行传输这两种数据传输模式之间的相互转换,而移位寄存器是达成这一目标的常用工具,能够支持并行及串行的数据输入与输出操作。 这些移位寄存器通常被设定为“串行输入、并行输出”(SIPO)或“并行输入、串行输出”(PISO)两种工作模式。 在串行数据输出的过程中,构成数据和字符的码元会按照既定的时间顺序逐位进行传输。 相比之下,并行数据传输则是在同一时刻将固定数量(普遍为8位或16位等)的数据和字符码元同时发送至接收端。 数据输入通常采用串行格式进行。 一旦数据成功输入寄存器,它便可以在所有输出端同时被读取,或者选择逐位移出。 寄存器中的每个触发器均设计为边沿触发类型,并且所有触发器均以特定的时钟频率协同工作。 对于每一个输入位而言,它需要经过N个时钟周期才能终在N个输出端呈现,从而完成并行输出。 值得注意的是,在串行加载数据期间,并行输出端的数据状态应保持稳定。 数据输入则采用并行格式。 在将数据写入寄存器的操作过程中,写/移位控制线必须暂时处于非工作状态;而一旦需要执行移位操作,控制线便会变为激活状态,并且寄存器会被锁定以保持当前状态。 只要时钟周期数不超过输入数据串的长度,数据输出端Q将按照预定的顺序逐位读出并行数据,并且必须明确区分低有效位(LSB)和高有效位(MSB)。
洛谷平台上,短路问题是一个常见的算法竞赛主题。常见的短路算法有Floyd算法、Bellman - Ford算法、Dijkstra算法和SPFA算法[^1]。 Floyd算法的时间复杂度为$O(n^3)$,Bellman - Ford算法的时间复杂度为$O(nm)$。Dijkstra算法的时间复杂度为$O(n^2)$,用堆优化之后的复杂度可以稳定在$O(n\log n)$ ,它是目前使用多的短路算法,在各大网络地图中都有应用,但不能求单点对单点的短路,只能将单点到所有点的短路求出,且仅适用于有向加权图,无法处理边为值的图。SPFA算法本质是Bellman - Ford算法的改良版本,更像一种贪心算法,时间复杂度为$O(km)$,但会被卡到$O(nm)$,虽有几种优化方法,但再好的优化也会被卡,所以大部分题建议使用Dijkstra算法加堆优化[^1]。 洛谷上有相关例题,如P3371 【模板】单源短路径(弱化版) 。还有短路计数问题,要求输出从顶点1到顶点$i$有多少条不同的短路,答案需对100003取模,若无法到达顶点$i$则输出0 [^1][^2]。同时,也有具体的代码示例用于解决求危险指数之和的小值问题,由于需要求多个点之间的距离,使用了Floyd算法,代码如下: ```cpp #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n, m; const int N = 300, M = 30000; int dist[N][N]; int a[M]; bool st[N]; int h[N], e[M], ne[M], w[M], idx; void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; } int main() { cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> a[i]; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cin >> dist[i][j];//输入距离 } } for (int k = 1; k <= n; k++)//模板 { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); } } } int sum = 0; for (int i = 2; i <= m; i++) { sum += dist[a[i - 1]][a[i]];//所有从i-1到i的小危险系数之和 } cout << sum << endl; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值