Newcoder Ramen Network Protocol (多源最短路)

版权声明:转载请标明出处 https://blog.csdn.net/weixin_41190227/article/details/89479960

链接:https://ac.nowcoder.com/acm/contest/624/D
来源:牛客网
 

You should have been heard of TCP and UDP. They are the most popular network protocols currently.

Recently, noodles, or more specifically, Ramen noodles, are discovered as a great material to make cables. And the new cable which is made from Ramen noodles is called Ramen Fiber. Ramen is a researcher of the Academy of Communication Mechanism and the core inventor of Ramen Fiber.

He also designs a new protocol which relies upon the exciting Ramen Fiber. The new protocol is named Ramen Network Protocol(RNP). In many aspects, the RNP works just like TCP and UDP. But here is one significant difference: the transmission between all Ramen Fibers is lossless, which means a packet will reach its destination while losing nothing. Why? It's the Ramen Power!

To measure the performance of RNP, Ramen wants to calculate the shortest time from any sender to any receiver if the packet has been transferred most optimally. He has set lots of senders and receivers, and an RNP powered LAN. But he is not good at writing benchmarks. As a good researcher as well as Ramen, can you help him with this tiny work to earn a nice meal?

输入描述:

The input contains multiple lines.

The first line is four integers: n, m, s, t(1 <= n <= 1e4, 1 <= m <= 5e4, 1 <= s,t <= n, s+t <= n), represents the number of nodes, RFs, senders and receivers.

The second line contains exactly s integers S1...Ss, each represents a distinct sender, for all 1 <= i <= s, 1 <= Si <= n.

The third line contains exactly t integers T1...Tt, each represents a distinct receiver, for all 1 <= i <= t, 1 <= Ti <= n.

Each of the next m lines contains three integers: u, v, w(1 <= u, v <= n, u ≠ v, 1 <= w <= 1e9), means that there is an RF between node u to node v and the time needed for a packet to go through it. All RFs are distinct.

It's guaranteed that no point is a sender and a receiver simultaneously.

输出描述:

If there is no packet can reach any receiver, output -1. Otherwise, output the shortest time in one single line.

示例1

输入

复制

10 14 3 3
1 4 9
6 8 10
1 2 12
2 3 4
2 8 4
3 4 5
3 5 5
3 8 9
3 9 1
3 10 8
4 5 2
5 6 7
5 7 6
6 7 14
7 9 11
7 10 23

输出

复制

9

说明

 

There are three routes will produce the shortest time: 4→5→64→5→6, 9→3→2→89→3→2→8 and 9→3→109→3→10.

示例2

输入

复制

4 2 2 2
1 2
3 4
1 2 1
3 4 1

输出

复制

-1

备注:

RNP makes no sense. Do not try to figure out what the description has said; it's useless.

题目大意:给你多个起点和多个终点。只要能到达一个终点就有解则输出最短路径。否则输出-1.

解题思路:对于多个起点,建立超级源点,让所有的起点与该超级源点距离为0;对于终点也要这么建图。最终只需要判断超级源点能否走到超级汇点就可以了。

找了一个晚上的bug,最后发现初始化距离的时候的那个INF(最大值)定义小了。。。还是写最短路的题少啊。

题目链接:https://ac.nowcoder.com/acm/contest/624/D

/*
@Author: Top_Spirit
@Language: C++
*/
#include <bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll, ll > P ;
const ll Maxn = 5e4 + 10 ;
const ll INF = 1e18 ;

struct Node {
    ll v, w, Next ;
}e[Maxn << 3];

ll head[Maxn], cnt = 0 ;
ll dis[Maxn], vis[Maxn] ;
ll n, m, s, t ;

void addEdge(ll u, ll v, ll w){
    e[cnt].v = v ;
    e[cnt].w = w ;
    e[cnt].Next = head[u] ;
    head[u] = cnt++ ;
}

void Dijkstra (ll s){
    memset(vis, 0 , sizeof(vis)) ;
    priority_queue < P, vector < P >, greater < P > > que ;
    while (!que.empty()) que.pop() ;
    for (ll i = 1; i <= n + 2; i++) dis[i] = INF ;
    dis[s] = 0 ;
    que.push(make_pair(0, s)) ;
    while (!que.empty()){
        P now = que.top() ;
        que.pop() ;
        ll p = now.second ;
        if (vis[p]) continue ;
        vis[p] = 1 ;
        for (ll i = head[p]; i != -1; i = e[i].Next){
            ll v = e[i].v ;
            ll w = e[i].w ;
            if (dis[v] > dis[p] + w) {
                dis[v] = dis[p] + w ;
                que.push(make_pair(dis[v], v)) ;
            }
        }
    }
}

int main (){
    while (cin >> n >> m >> s >> t){
        cnt = 0 ;
        memset(head, -1, sizeof(head)) ;
        memset(e, 0, sizeof(e)) ;
        memset(dis, 0, sizeof(dis)) ;
        ll u, v, w ;
        for (ll i = 0; i < s; i++){
            cin >> u ;
            addEdge(n + 1, u, 0) ;
        }
        for (ll i = 0; i < t; i++){
            cin >> u ;
            addEdge(u, n + 2, 0) ;
        }
        for (ll i = 0; i < m; i++){
            cin >> u >> v >> w ;
            addEdge(u, v, w) ;
            addEdge(v, u, w) ;
        }
        Dijkstra(n + 1) ;
        if (dis[n + 2] == INF) cout << -1 << endl ;
        else cout << dis[n + 2] << endl ;
    }
    return 0 ;
}

猜你喜欢

转载自blog.csdn.net/weixin_41190227/article/details/89479960