zoukankan      html  css  js  c++  java
  • 2019南昌网络赛 Fire-Fighting Hero

    有一个消防队英雄,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
    ", maxhero <= maxfire * C ? maxhero : maxfire);
    }
    int main(){
        int t;
        scanf("%d", &t);
        while(t--) solve();
    }
    
  • 相关阅读:
    Java实现 LeetCode 56 合并区间
    JQuery实现对html结点的操作(创建,添加,删除)
    JQuery实现对html结点的操作(创建,添加,删除)
    JQuery实现对html结点的操作(创建,添加,删除)
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 54 螺旋矩阵
    Java实现 LeetCode 54 螺旋矩阵
    Java实现 LeetCode 54 螺旋矩阵
  • 原文地址:https://www.cnblogs.com/Emcikem/p/13514595.html
Copyright © 2011-2022 走看看