题解:HDOJ 选择最佳路线

有一天,琪琪想乘坐公交车去拜访她的一位朋友。

由于琪琪非常容易晕车,所以她想尽快到达朋友家。

现在给定你一张城市交通路线图,上面包含城市的公交站台以及公交线路的具体分布。

已知城市中共包含 nn 个车站(编号11~nn)以及 mm 条公交线路。

每条公交线路都是 单向的,从一个车站出发直接到达另一个车站,两个车站之间可能存在多条公交线路。

琪琪的朋友住在 ss 号车站附近。

琪琪可以在任何车站选择换乘其它公共汽车。

请找出琪琪到达她的朋友家(附近的公交车站)需要花费的最少时间。

输入格式

输入包含多组测试数据。

每组测试数据第一行包含三个整数 n,m,sn,m,s,分别表示车站数量,公交线路数量以及朋友家附近车站的编号。

接下来 mm 行,每行包含三个整数 p,q,tp,q,t,表示存在一条线路从车站 pp 到达车站 qq,用时为 tt。

接下来一行,包含一个整数 ww,表示琪琪家附近共有 ww 个车站,她可以在这 ww 个车站中选择一个车站作为始发站。

再一行,包含 ww 个整数,表示琪琪家附近的 ww 个车站的编号。

输出格式

每个测试数据输出一个整数作为结果,表示所需花费的最少时间。

如果无法达到朋友家的车站,则输出 -1。

每个结果占一行。

数据范围

n≤1000,m≤20000n≤1000,m≤20000,
1≤s≤n1≤s≤n,
0<w<n0<w<n,
0<t≤10000<t≤1000

输入样例:

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

输出样例:

1
-1
/*
建立一个超级源点使得琪琪到他家车站的距离为0;
*/
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010, M = 21010, INF = 0x3f3f3f3f;

int id[N];
bool st[N];
int n, m, E;
int dist[N];
int h[N], e[M], ne[M], w[M], idx;

void add(int a, int b, int c)
{
    e[idx] = b;
    w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx;
    idx ++ ;
}

void dijkstra()
{
    memset(st, false, sizeof st);
    memset(dist, 0x3f, sizeof dist);
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    
    dist[0] = 0;
    heap.push({dist[0], 0});
    
    while (heap.size())
    {
        auto t = heap.top();
        heap.pop();
        
        int ver = t.y, distance = t.x;
        
        if (st[ver]) continue;
        st[ver] = true;
        
        for (int i = h[ver]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > dist[ver] + w[i])
            {
                dist[j] = dist[ver] + w[i];
                heap.push({dist[j], j});
            }
        }
    }
    
}

int main()
{
    while(cin >> n >> m >> E)
    {
        idx = 0;
        memset(h, -1, sizeof h);
        
        while (m -- )
        {
            int a, b, c;
            scanf("%d %d %d", &a, &b, &c);
            add(a, b, c);
        }
        
        int cnt;
        cin >> cnt;
        for (int i = 0; i < cnt; i ++ )
        {
            int k;
            scanf("%d", &k);
            add(0, k, 0);
        }
        
        dijkstra();
        
        int res = INF;
        res = min(res, dist[E]);
        if (res == INF) puts("-1");
        else printf("%d\n", res);
    }
    
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥也不会hh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值