ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

灾后重建

2022-05-25 13:32:26  阅读:141  来源: 互联网

标签:include int cin ++ 灾后 now 重建


灾后重建

P1119 灾后重建 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

floyd

本题考查 floyd 算法的本质:

for (int k = 1; k <= n; k++)
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			f[i][j] = min(f[i][j], f[i][k] + f[k][j])

第一层循环 k 表示 i 号点 只能经过 1 - k 号点中转 到达 j 号点的最短距离

因此本题求解各个询问的过程相当于把 floyd 拆解出来,每当一个点被重建,意思为可以经过这个点中转更新最短距离,由于询问和点的重建时间都是非递减顺序,因此第 1 个点重建,就是 k = 1 跑一次后两层循环;第 2 个点重建,就是 k = 2 跑一次后两层循环 。。。

因此所有点重建的更新过程相当于只跑了一遍完整的 floyd,复杂度为 \(O(n^3+q)\)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
typedef long long ll;

const int N = 2e2 + 10;
const int INF = 0x3f3f3f3f;
int n, m;
int g[N][N];
int a[N];
void updata(int now)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			g[i][j] = min(g[i][j], g[i][now] + g[now][j]);
}
int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	memset(g, 0x3f, sizeof g);
	for (int i = 0; i < n; i++)
		g[i][i] = 0;
	while(m--)
	{
		int i, j, w;
		cin >> i >> j >> w;
		g[i][j] = g[j][i] = w;
	}
	int q;
	cin >> q;
	int now = 0;
	while(q--)
	{
		int x, y, t;
		cin >> x >> y >> t;
		while(a[now] <= t && now < n)
		{
			updata(now);
			now++;
		}
		if (a[x] > t || a[y] > t)
			cout << -1 << endl;
		else
		{
			if (g[x][y] == INF)
				cout << -1 << endl;
			else
				cout << g[x][y] << endl;
		}
	}
	return 0;
}

标签:include,int,cin,++,灾后,now,重建
来源: https://www.cnblogs.com/hzy717zsy/p/16308980.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有