洛谷1119 图论

题目大意:村庄受损道路完好。
给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的。并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车。若t[i]为0则说明地震未对此地区造成损坏,一开始就可以通车。之后有Q个询问(x, y, t),对于每个询问你要回答在第t天,从村庄x到村庄y的最短路径长度为多少。如果无法找到从x村庄到y村庄的路径,经过若干个已重建完成的村庄,或者村庄x或村庄y在第t天仍未重建完成 ,则需要返回-1。

这道题与常见的灾后重建有类似又有不同:常见的灾后重建是村庄完好重建道路,往往是跑最短路或最小生成树的模板,但此题是村庄受损道路完好,想到与点关系密切的最短路算法就只有floyd.再看这道题的N只有200,更加肯定了是floyd。

思路是:对于每个询问,去依次枚举这个询问前恢复了的每个点。
这题和Floyd模板不同的是用了2个数组,g[][]和dis[][]来跑floyd,因为对于每个询问,恢复的点都不同,dis[a][b]表示当前这个询问时a到b的最短路程,而g[a][b]表示若所有点都可用时a到b的最短路程。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 100;
const int inf = 0x3f3f3f3f;
int dis[202][202],t[202],n,m,q,x,y,ti,a,b,w,g[202][202];
int main()
{
    memset(dis,inf,sizeof(dis));
    memset(g,inf,sizeof(g));
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; ++i)  scanf("%d",&t[i]);
    for(int i = 1; i <= m; ++i) 
    {
        scanf("%d%d%d",&a,&b,&w);
        g[a][b] = g[b][a] = w;
    }
    sort(t, t + n);
    for(int i = 0; i < n; ++i) g[i][i] = 0;

    scanf("%d",&q);
    for(int i = 1,j = 0; i <= q; ++i)
    {
        scanf("%d%d%d",&x,&y,&ti);
        while(t[j] <= ti && j < n)
        {   
            for(int a = 0; a < n; ++a)
                for(int b = 0; b < n; ++b)
                if(a != b)
                {

                    g[a][b] = min(g[a][b],g[a][j] + g[j][b]);
                    if(t[a] <= ti && t[b] <= ti)
                    {
                        dis[a][j] = min(g[a][j],dis[a][j]);dis[j][b] = min(dis[j][b],g[j][b]);
                        dis[a][b] = min(dis[a][b],dis[a][j] + dis[j][b]);
                    }
                }
            ++j;
        }
        if(dis[x][y] == inf) printf("-1\n");
        else printf("%d\n",dis[x][y]);  
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷(Luogu)是一个知名的在线编程题库和竞赛平台,2404 题目通常是指某一道具体的算法题目。在洛谷上,题目编号为2404的问题可能涉及各种难度和主题,比如数组、字符串、图论、动态规划等。 要解决“洛谷2404”,你需要按照以下步骤操作: 1. **了解题目**:首先,访问洛谷官网(https://www.luogu.com.cn/problem/2404),阅读题目描述,理解问题背景、输入输出格式以及限制条件。 2. **分析问题**:根据题目类型,思考可能用到的数据结构和算法。例如,如果是动态规划问题,可能会涉及到状态转移方程;如果是搜索或图论,可能是深度优先搜索、广度优先搜索或者最短路径算法。 3. **制定策略**:设计出解题思路,并确定代码编写的大致框架。如果题目包含样例测试数据,可以通过输入样例检查初始答案是否正确。 4. **编码实现**:使用一种支持在线提交的语言(如C++、Python、Java等)编写代码,将你的解决方案转化为程序。 5. **调试运行**:在本地编译器或洛谷的在线评测环境中,运行你的代码,看是否会得到预期的结果。如果结果不正确,根据错误提示调整代码。 6. **优化完善**:如果代码能解决问题但性能不佳,可能需要对算法进行优化。对于一些复杂的问题,可能还需要考虑边界条件和特殊情况。 7. **提交并查看评论**:最后,提交你的代码并查看系统给出的结果,如果有错误或不符合预期,再返回修改。 如果你遇到了具体的技术难题,可以说出详细点,我会尽力帮助解答相关的概念或提供解题建议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值