hdoj 2680 Choose the best route

Choose the best route


Problem Description
One day , Kiki wants to visit one of her friends. As she is liable to carsickness , she wants to arrive at her friend’s home as soon as possible . Now give you a map of the city’s traffic route, and the stations which are near Kiki’s home so that she can take. You may suppose Kiki can change the bus at any station. Please find out the least time Kiki needs to spend. To make it easy, if the city have n bus stations ,the stations will been expressed as an integer 1,2,3…n.
 

Input
There are several test cases.
Each case begins with three integers n, m and s,(n<1000,m<20000,1=<s<=n) n stands for the number of bus stations in this city and m stands for the number of directed ways between bus stations .(Maybe there are several ways between two bus stations .) s stands for the bus station that near Kiki’s friend’s home.
Then follow m lines ,each line contains three integers p , q , t (0<t<=1000). means from station p to station q there is a way and it will costs t minutes .
Then a line with an integer w(0<w<n), means the number of stations Kiki can take at the beginning. Then follows w integers stands for these stations.
 

Output
The output contains one line for each data set : the least time Kiki needs to spend ,if it’s impossible to find such a route ,just output “-1”.
 

Sample Input
  
  
5 8 5 1 2 2 1 5 3 1 3 4 2 4 7 2 5 6 2 3 5 3 5 1 4 5 1 2 2 3 4 3 4 1 2 3 1 3 4 2 3 2 1 1
 

Sample Output
  
  
1 -1
 


题目大意:

有一天,kiki想去她的一个朋友。 她很容易晕车,她想尽快到达朋友家。 现在给你一个城市的交通路线,和kiki的家附近的车站, 你可以设想Kiki可以在任何车站的改变公共汽车。 如果这座城市有n个车站,车站将被表示为一个整数1、2、3…n。请找出Kiki最少需要花费的时间?

解题思路:

这道题有一定的技巧性,刚开始做的时候不知道怎么回事感觉自己做的没问题可是一直超时,把我真的是气坏了,太悲催了。
后来百度了一下怎么解决超时的问题,可是还没有找到解决的方法,百度上只是说算法不够优化。可是我真的不知道该怎么优化。
后来同讲了以后才知道要从相反的反向考虑,即把终点当作起点,这样只进行了一个dijkstra降低了时间的复杂度,真的优化啦。
还要注意一点就是:
在给map数组赋值的话也需要反着赋值,原来的p-q,要改为q-p,这道题不能当做无向图要当做有向图处理,
虽然做这道题浪费了不少时间,但是从做题中也学到许多知识,虽然没做几道题,感觉还是有收获的。

#include<iostream>
#include<cstdio>
#define INF 0x3f3f3f3f
#include<algorithm>
const int maxn=1010;
using namespace std;
int d[maxn];
int used[maxn];
int map[maxn][maxn];
int n;
void dijkstra(int s)
{
	for(int i=1;i<=n;i++)
	{
		d[i]=INF;
		used[i]=0;
	}
	d[s]=0;
	while(1)
	{
		int v=-1;
		for(int i=1;i<=n;i++)
			if(!used[i]&&(v==-1||d[i]<d[v]))
				v=i;
		if(v==-1) break;
		used[v]=1;
		for(int i=1;i<=n;i++)
			d[i]=min(d[i],d[v]+map[v][i]);	
	} 
}
int main()
{
	int m,s;
	while(scanf("%d%d%d",&n,&m,&s)!=EOF)
	{
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				if(i==j)
					map[i][j]=0;
				else
					map[i][j]=INF;
			}
		int p,q,t,w,g;	
		for(int i=0;i<m;i++)
		{
			scanf("%d%d%d",&p,&q,&t);
			if(map[q][p]>t)
				map[q][p]=t;
		}
		scanf("%d",&w);
		int minn=INF;
		dijkstra(s);
		while(w--)
		{		
			scanf("%d",&g);
			minn=min(minn,d[g]);
		}
		if(minn>=INF)
			printf("-1\n");
		else
			printf("%d\n",minn);	
	}
	return 0;
 } 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值