20201009day30 刷题记录

1 P1119 灾后重建

problem

对于每个时间点,询问两点之间的路径(针对不同时间点各个点之间连通性不同)

solution

Floyd的本质是中转:

for(k=1;k<=n;k++)
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            if(e[i][j]>e[i][k]+e[k][j])
                 e[i][j]=e[i][k]+e[k][j];            

本题:按照时间顺序更新每一个点可用的点(即为修建好村庄),对于每个时间点询问,求对于目前建设的所有村庄来说任意两点之间的最短路。
与floyd中使用前k个节点更新最短路的思维一致。

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define N 205
int n,m;
int a[N],f[N][N];
void update(int k){
	for(int i=0;i<n;i++) for(int j=0;j<n;j++) 
		if(f[i][j]>f[i][k]+f[j][k])
			f[i][j]=f[i][k]+f[j][k];
	return ;
}
int read(){
	int op=1,ans=0;
	char c;
	c=getchar();
	for(;(c<'0'||c>'9')&&c!='-';c=getchar());
	if(c=='-') op=-1,c=getchar();
	for(;c>='0'&&c<='9';c=getchar()) ans*=10,ans+=c^48;
	return ans*op;
}
int main(){
	n=read(),m=read();
	//printf("%d %d",n,m);
	for(int i=0;i<n;i++) a[i]=read();
	for(int i=0;i<n;i++) for(int j=0;j<n;j++) f[i][j]=1e9;
	for(int i=0;i<n;i++) f[i][i]=0;
	int s1,s2,s3;
	for(int i=0;i<m;i++) {
		s1=read(),s2=read(),s3=read();
		f[s1][s2]=f[s2][s1]=s3;
	}
	int q;q=read();
	int now=0;
	for(int i=1;i<=q;i++){
		s1=read(),s2=read(),s3=read();
		while(a[now]<=s3&&now<n){
			update(now);//依次更新
			now++;
		}
		if(a[s1]>s3||a[s2]>s3) printf("-1
");
		else {
			if(f[s1][s2]==1e9) printf("-1
");
			else printf("%d
",f[s1][s2]);
		}
	}
	return 0;
}	

后记

感觉代码很好理解啊

2

要做就做南波万
原文地址:https://www.cnblogs.com/liuziwen0224/p/20201009day30-003.html