【题目】跨栏题解

【题目】

题目描述

校运会快开始了,小花正在练习跨栏。 显然,对于运动员跳过几个矮栏是很容易的,但是高栏却很难。于是,小花非常关心路径上最高的栏的高度。

学校的训练场中有 N 个站台,分别标记为 1,2,3,…,N。所有站台之间有 M 条单向路径,第 i 条路经是从站台 Si​ 开始,到站台 Ei​,其中最高的栏的高度为 Hi​。无论如何跑,小花都要跨栏。

小花有 T 个训练任务要完成。第 i个任务包含两个数字 Ai​ 和 Bi​,表示小花必须从站台 Ai​ 跑到站台 Bi​,可以路过别的站台。小花想找一条路径从站台 Ai​ 到站台 Bi​,使路径上最高的栏的高度最小。 你的任务就是写一个程序,计算出路径上最高的栏的高度的最小值。

输入格式

第一行:三个空格隔开的整数 N, M, T。

接下来 M 行:第 i 行包含三个空格隔开的整数 Si​,Ei​,Hi​。

接下来 T行:第 i 行包含两个空格隔开的整数,表示任务 ii 的起始站台和目标站台 Ai​,Bi​。

输出格式

T 行:第 i 行为一个整数,表示任务 i路径上最高的栏的高度的最小值。如果无法到达,输出 -1

样例 #1

样例输入 #1

5 6 3
1 2 12
3 2 8
1 3 5
2 5 3
3 4 4
2 4 8
3 4
1 2
5 1

样例输出 #1

4
8
-1

提示

对于 100%的数据1<=N<=300,1<=M<=250000,1<=Hi<=1000000,1<=T<=40000,1<=Ai,Bi<=N

【思路】

1.初始化:将a数组先设为无穷大,然后输入,建边

    int n,m,l;
	scanf("%d%d%d",&n,&m,&l);
	memset(a,0x3f,sizeof(a));
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		a[x][y]=z;
	}

2.使用floyd算法,因为N<=300,比较小,O(N^3)不会超时,而且明显是全局最短路

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

注意:这个代码只是框架,还要在上面做些改动

因为题目说是求中间最大值,不是最短路,所以将a[i][k]+a[k][j]变成max(a[i][k],a[k][j]),就OK了

3.最后输出一下就行了,注意要判断-1

怎么判断呢?

因为我们最开始使用了memset(a,0x3f,sizeof(a)),所以判断一下a[i][j]是否为0x3f3f3f3f就行了

如果a[i][j]=0x3f3f3f3f的话:输出-1

否则:输出a[i][j]

    for(int i=1;i<=l;i++){
		int x,y;
		cin>>x>>y;
		if(a[x][y]==0x3f3f3f3f){
			cout<<-1<<endl;
		}
		else{
			cout<<a[x][y]<<endl;
		}
	}

【完整代码】

那么很容易就得到了完整代码了

#include<bits/stdc++.h>
using namespace std;
int a[305][305];
int main(){
	int n,m,l;
	scanf("%d%d%d",&n,&m,&l);
	memset(a,0x3f,sizeof(a));
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		a[x][y]=z;
	}
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				a[i][j]=min(a[i][j],max(a[i][k],a[k][j]));
			}
		}
	}
	for(int i=1;i<=l;i++){
		int x,y;
		cin>>x>>y;
		if(a[x][y]==0x3f3f3f3f){
			cout<<-1<<endl;
		}
		else{
			cout<<a[x][y]<<endl;
		}
	}
	return 0;
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值