2019南昌网络赛 Fire-Fighting Hero - 最短路 DIjkstra

有一个消防队英雄,k个消防队成员,进行比赛,消防队英雄到达n个点的最短路的最大值和消防队成员到达n个点的最短路的最大值的C倍进行比较

方法1:
跑一次DIjkstra,从消防队英雄出发,然后跑K次最短路,求出值即可
方法2:
建立辅助点0点,0点到K个消防队成员有一个有向边,然后跑2次最短路,求出最大值即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define ll long long
using namespace std;
const int INF = 2147483647;
const int N = 1e3 + 5;
const int M = 1e6 + 5;
ll dis[N];//存路径
bool vis[N];
struct edge{
    int next, to, w;
}e[M];
int head[N], tot;
inline void add(int u, int v, int w){//链式前向星存图
    e[++tot].to = v;
    e[tot].w = w;
    e[tot].next = head[u];
    head[u] = tot;
}
struct node{
    ll dis;//dis表示到起始点的距离
    int pos;//pos表示该点的下标
    bool operator < (const node &x)const{//符号重载,对距离排序,针对于在优先队列里
        return x.dis < dis;
    }
};
void dijkstra(int s, int n){
    for(int i = 0; i <= n; i++) dis[i] = INF, vis[i] = 0;
    dis[s] = 0;
    
    std::priority_queue<node> q;//构造优先队列
    q.push((node){dis[s], s});//把初始位置和距离放进优先队列
    while(!q.empty()){
        node tmp = q.top();
        q.pop();
        int u = tmp.pos;
        if(vis[u]) continue;//如果这个点走过了
        vis[u] = 1;//标记走过
        for(int i = head[u]; i; i = e[i].next){
            int v = e[i].to;
            if(!vis[v] && dis[v] > dis[u] + e[i].w){
                dis[v] = dis[u] + e[i].w;
                q.push((node){dis[v], v});
            }
        }
    }
}
int super[N];
ll teamdis[N];
void solve(){
    int V, E, S, K, C;
    tot = 0;
    memset(head, 0, sizeof(head));
    memset(teamdis, 0x3f, sizeof(teamdis));
    scanf("%d%d%d%d%d", &V, &E, &S, &K, &C);
    for(int i = 1; i <= K; i++) 
        scanf("%d", &super[i]), add(0, super[i], 0);
    for(int i = 1; i <= E; i++){
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        add(u, v, w); add(v, u, w);
    }
    dijkstra(S, V);
    ll maxhero = 0;
    for(int i = 1; i <= V; i++) 
        maxhero = max(maxhero, dis[i]);
    ll maxfire = 0;
    dijkstra(0, V);
    for(int i = 1; i <= V; i++)
        maxfire = max(maxfire, dis[i]);
    printf("%lld\n", maxhero <= maxfire * C ? maxhero : maxfire);
}
int main(){
    int t;
    scanf("%d", &t);
    while(t--) solve();
}
posted @ 2020-08-16 21:55  Emcikem  阅读(134)  评论(0编辑  收藏  举报