[Question solution] Luogu P1119 post-disaster reconstruction

Go to: My own blog

topic

Luogu P1119 post-disaster reconstruction

answer

Since the number of queries Q is relatively large, it is impossible to create a new map every time you query, so consider offline (centralized processing of queries). Note that the reconstruction time of villages is not strictly increasing, so before time t[i], only the villages numbered 0~i are reconstructed. Note that the number of villages n is relatively small, you can consider the floyd algorithm, this algorithm can find the shortest path between any two points, at the same time, in the process of dynamic planning, the floyd algorithm also solves the problem of "if only passing through the nodes numbered 0~i , Find the shortest path between any two points" this sub-problem. Therefore, while executing the floyd algorithm, the answers to the queries that meet the current conditions are updated.

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=200+5;
const int maxq=5e4+5;
int n,m,q;
int d[maxn][maxn],ti[maxn];
struct question{int x,y,t,ans;}a[maxq];
inline void floyd()
{
	for(int i=0;i<n;i++) d[i][i]=0;
	for(int k=0;k<n;k++)
	{
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
		for(int i=q;i>=1&&ti[k]<=a[i].t;i--) 
			if(a[i].x<=k&&a[i].y<=k) a[i].ans=min(a[i].ans,d[a[i].x][a[i].y]);	 
	}	//注意floyd算法在第k轮求出的d[][],并不能保证路径的起点和终点属于编号为0~k的节点 
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) scanf("%d",&ti[i]);
	memset(d,0x3f,sizeof(d));
	for(int i=1;i<=m;i++) 
	{
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		d[x][y]=d[y][x]=z;
	}
	scanf("%d",&q);
	for(int i=1;i<=q;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].t),a[i].ans=inf;
	floyd();
	for(int i=1;i<=q;i++) 
	{
		if(a[i].ans==inf) printf("-1\n");
		else printf("%d\n",a[i].ans);
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/zjgmartin/article/details/108415420