其他分享
首页 > 其他分享> > 【ICPC银川网络赛F题】【luogu1119灾后重建】插入点的floyd

【ICPC银川网络赛F题】【luogu1119灾后重建】插入点的floyd

作者:互联网

【ICPC银川网络赛F题】题目大意:t组数据。有n个城市,每个城市有ai点危险值。给定一个邻接矩阵即两个城市的距离。有q组询问,问从u城市到v城市在不经历w危险值城市的情况下最短路是多少。
【luogu1119灾后重建】题目大意:给定n个点和m条边,每个点的重修时间为ti。有q组询问,问从u城市到v城市在第p天时的最短路是多少?

【ICPC银川网络赛F题】
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n,q;
int s[222][222],ans[202020];
struct pro1
{
	int u,v,w,num;
}e[202022];
struct pro2
{
	int W,num;
}f[202022];
bool cmp1(pro1 a,pro1 b)
{
	return a.w<b.w;
}
bool cmp2(pro2 a,pro2 b)
{
	return a.W<b.W;
}
int main()
{
	scanf("%d%d",&n,&q);
	for(int i=1; i<=n; i++)
	{
		scanf("%d",&f[i].W);
		f[i].num=i;
	}
	for(int i=1; i<=n; i++)
		for(int j=1; j<=n; j++)
			if(i!=j)
				s[i][j]=1e8;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=n; j++)
			scanf("%d",&s[i][j]);
	for(int i=1; i<=q; i++)
	{
		scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
		e[i].num=i;
	}
	sort(e+1,e+1+q,cmp1);
	sort(f+1,f+1+n,cmp2);
	int k=f[1].num,kk=1;
	for(int i=1; i<=q; i++)
	{
		while(f[kk].W<=e[i].w&&kk!=n+1)
		{
			for(int j=1; j<=n; j++)
				for(int l=1; l<=n; l++)
					if(j!=l)
						s[j][l]=min(s[j][l],s[j][k]+s[k][l]);
			kk++;
			k=f[kk].num;
		}
		ans[e[i].num]=s[e[i].u][e[i].v];
	}
	for(int i=1; i<=q; i++)
		printf("%d\n",ans[i]);
	cout<<endl;
	return 0;
}
【luogu1119灾后重建】
#include <iostream>
#include <cstdio>
using namespace std;
int n,m,x,y,z,v,q;
int t[220],f[220];
int s[220][220];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0; i<=n; i++)
		for(int j=0; j<=n; j++)
			t[i]=s[i][j]=s[j][i]=19991215;
	for(int i=0; i<n; i++)
		scanf("%d",&t[i]);
	
	for(int i=1; i<=m; i++)
	{
		scanf("%d%d%d",&x,&y,&v);
		s[x][y]=s[y][x]=v;
	}
	int k=0;
	scanf("%d",&q);
	for(int i=1; i<=q; i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		while(t[k]<=z)
		{
			for(int j=0; j<n; j++)
				for(int l=0; l<n; l++)
					s[j][l]=min(s[j][l],s[j][k]+s[k][l]);
			k++;
		}
		if(s[x][y]==19991215 || t[x]>z || t[y]>z)
			printf("-1\n");
		else
			printf("%d\n",s[x][y]);
	}
	return 0;
}

两个题如出一辙
1.将城市危险值/重修时间从小到大排序,陆续加点,内部跑弗洛伊德一直更新两点最短路,灾后重建保证ti从小到大排序,F题需要将两数组从小到大排序。
2.加点方式为 最外层枚举 枚举当前的危险值,此时已经加入了一个新点,然后两个for循环即为floyed,当前这个点其实为floyd最外层的点。灾后重建也同理。

标签:luogu1119,int,城市,ICPC,floyd,灾后,include,重建,220
来源: https://blog.csdn.net/LH_991215/article/details/100175940