杭电2680(dijkstra求几条最短路中最短的一条)

Choose the best route(难度:1)

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)

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

思路:

Floyd超时,用dijkstra算法,超时就把输入输出换成scanf和printf。
由于有多个起点,所以将终点当做起点,反向求解。
由于有多条最短路,所以引入一个变量min,循环求最小值。

AC代码:

#include <string.h>
#include <iostream>
#include <stdio.h>
#define INF 0xffffff
#define maxn 1010

using namespace std;

int ttime[maxn][maxn];//两点间距离
int vis[maxn];//结点是否已经访问过
int dis[maxn];//到结点的最短距离
int n;

void dijkstra(int start)
{
    int k=start,min;
    //初始化所有节点都不在最短路径中
    memset(vis,0,sizeof(vis));
    //初始化从起始结点到结点i的时间
    for(int i=1;i<=n;i++)
    {
        dis[i]=ttime[start][i];
    }
    //起始结点到起始结点时间为0,并标记为已走 
    dis[start]=0;
    vis[start]=1;
    //依次标记n-1个结点
    for(int i=1;i<=n;i++)
    {
        //初始化 
        min=INF;
        //找到i所直接连通的结点中具有最短时间的结点
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]<min)
            {
                //更新最短时间,保存达这个点
                min=dis[j];
                k=j;
            }
        }
        dis[k]=min;
        //标记这个点
        vis[k]=1;
        //判断是起始结点到j短,还是经过k连接j更短
        for(int j=1;j<=n;j++)
        {
            if(dis[j]>ttime[k][j]+dis[k])
            {
                dis[j]=ttime[k][j]+dis[k];
            }
        }
    }
}
int main()
{
    int m,s;
    int p,q,t;
    int src,w;
    while(scanf("%d%d%d",&n,&m,&s)!=EOF)
    {
        //init
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                ttime[i][j]=INF;
            }
        }

        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&p,&q,&t);
            if(ttime[q][p]>t) ttime[q][p]=t;
        }
        scanf("%d",&src);
        int tmin=INF;
        dijkstra(s);
        for(int i=0;i<src;i++)
        {
            scanf("%d",&w);
            if(tmin>dis[w]) tmin=dis[w];
        }
        if(tmin==INF) printf("-1\n");
        else printf("%d\n",tmin);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值