HDU2851--Lode Runner--最短路

Description

Lode Runner is a famous game, I think you played in your childhood.


Ok, now, I simple the problem. In the game, it has N horizontal roads, the ladders always stay at right side vertically, and the ladders are extending towards up and down with unlimited length. If ladder near or cross a road, little WisKey will walk on the road by climbed the ladder. Two roads were covered by each other in the X-axis; it will be considered can be passing through. Each road has an integer W means the dangerous level.

Little WisKey must start at No.1 road, and he can’t go back, he always go ahead. WisKey want to go some roads, so he needs to know how minimum sum of dangerous will happen. You can finish the game, yes?
 

Input

The first integer C represents the number of cases, And C cases followed.
  
Each test case contains a single integer N roads (1<=N<= 2000) and M destinations (1<=M<=500). The next N line contains three integers Si, Ei, Wi, meaning the road build from Si to Ei, and the Wi dangerous level (0 <= Si <= Ei <= 1000, 1 <= Wi <= 1000). And the roads sorted by Ei increasing yet. The last M line contains integers mean little WisKey’s destinations.
 

Output

  
For each questions, output the minimum sum of dangerous. If can’t reach the goal, please print -1.
 

Sample Input

    
    
3 10 4 1 4 7 5 6 3 3 7 5 2 9 8 10 13 8 12 14 11 11 15 13 16 18 5 17 19 6 8 20 9 1 2 3 10 5 5 1 4 5 3 6 10 5 8 20 2 9 1 7 10 2 1 2 3 4 5 4 4 1 5 1 2 7 20 2 7 3 7 9 4 1 2 3 4
 

Sample Output

    
    
7 -1 12 24 5 15 35 6 8 1 21 4 8
 
//必须在这个之前的区间找中介区间
//已经到了目前区间,就不能跳到前面区间,也就是循环从下一个区间开始寻找匹配的
//用结构体来区间
//此题需要注意的地方在于剪枝,想想,我们循环一遍给每个区间找最短路,注意比如我们给第7个区间找最短路,
只能通过前6个区间到达他,不能我跳到第八个,再回来。
所以,剪枝就出来了,一个区间的最短路就是前面所求出的存在最短路的区间,所能到达的最短
#include <iostream>
#include <cstdio>
#include <queue>
#define maxn 1008
#define inf 0x7fffffff
using namespace std;
int visit[2008];//用来判断最短路是否已经求出
struct QJ
{
	int low,high,dan,mindan;
}qj[2008];
int main()
{
	int t,n,m;
	scanf("%d",&t);
	while(t--)
	{
		memset(visit,0,sizeof(visit));
		scanf("%d%d",&n,&m);//m个目的地,n个区间
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d%d",&qj[i].low,&qj[i].high,&qj[i].dan);
		}
		for(int z=2;z<=n;z++)
		{
				qj[z].mindan=inf;
		}
		qj[1].mindan=qj[1].dan;//mindan表示从1区间到该区间的最小危险和
		visit[1]=qj[1].mindan;
		for(int i=2;i<=n;i++)
		{
			bool flag=false;
			for(int j=1;j<i;j++)
			{
				if(visit[j])
				{
					if(qj[j].high>=qj[i].low&&qj[j].mindan+qj[i].dan<qj[i].mindan)
					{
						flag=true;
						qj[i].mindan=qj[j].mindan+qj[i].dan;
					}
				}
			}
			if(flag)
			{
				visit[i]=qj[i].mindan;
			}
		}
		for(int i=1;i<=m;i++)
		{
			int mudi;
			scanf("%d",&mudi);
			if(visit[mudi])
			{
				printf("%d\n",qj[mudi].mindan);
			}
			else printf("%d\n",-1);
		}
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值