• 【 最短路 && 思维 】Escape Plan


    • Step1 Problem:

    原题 一个人要逃出城市,给出一个图,但每个节点上有对应的d[i]个怪兽,怪兽会依次堵住当前最短的一条路,给出k个逃生点,请帮他计算一下最坏情况下他能逃出城市的最短时间。

    • Step2 Ideas:

    从k个逃生点反向跑到起点,这样可以保证到当前点的路一定是可以走的路,用n个优先队列维护出第 d[i] + 1 个小的dis值便是当前点的所能走的最短路

    • Step3 code:

    /**
    * Youth gives you light please don't let it down.
    * ▄▄▄▄▄
    *            ▀▀▀██████▄▄▄       _______________
    *          ▄▄▄▄▄  █████████▄  /                 
    *         ▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Gotta go fast!   |
    *       ▀▀█████▄▄ ▀██████▄██ | _________________/
    *       ▀▄▄▄▄▄  ▀▀█▄▀█════█▀ |/
    *            ▀▀▀▄  ▀▀███ ▀       ▄▄
    *         ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌   ______________________________
    *       ██▀▄▄▄██▀▄███▀ ▀▀████      ▄██  █                              \
    *    ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███     ▌▄▄▀▀▀▀█_____________________________//
    *    ▌    ▐▀████▐███▒▒▒▒▒▐██▌
    *    ▀▄▄▄▄▀   ▀▀████▒▒▒▒▄██▀
    *              ▀▀█████████▀
    *            ▄▄██▀██████▀█
    *          ▄██▀     ▀▀▀  █
    *         ▄█             ▐▌
    *     ▄▄▄▄█▌              ▀█▄▄▄▄▀▀▄
    *    ▌     ▐                ▀▀▄▄▄▀
    *     ▀▀▄▄▀     ██
    *   ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
    * - ▌          GNU C++17 7.3.0            ▀ ▀
    *  - ▌                                         ▀
    * /- ▌            Go Go Go !               ▀ ▀
    * /  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
    *               ██
    **/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<bitset>
    #include<cassert>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<deque>
    #include<iomanip>
    #include<list>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define lt k<<1
    #define rt k<<1|1
    #define int ll
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define mem(a, b) memset(a, b, sizeof(a))
    const double pi = acos(-1.0);
    const double eps = 1e-6;
    const ll mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const int maxn = 1e6 + 5;
    int head[maxn], cnt, dis[maxn];
    bool vis[maxn];
    int e[maxn], d[maxn];
    int n, m, k;
    
    struct node
    {
        int v, w;
        node () {}
        node(int a, int b) {v = a, w = b;}
        bool operator < (const node & b) const { return w > b.w;}
    };
    
    struct Edge
    {
        int v, w, next;
        Edge () {}
        Edge(int a, int b, int c) {v = a, w = b, next = c;}
    } edge[maxn * 2];
    
    void add_edge(int u, int v, int w)
    {
        edge[cnt] = (Edge) {v, w, head[u]};
        head[u] = cnt++;
        edge[cnt] = (Edge) {u, w, head[v]};
        head[v] = cnt++;
    }
    priority_queue<int> di[maxn];
    
    void dij()
    {
        priority_queue<node> q;
        for(int i = 0; i < k; i++)
        {
            dis[e[i]] = 0;
            q.push((node){e[i], dis[e[i]]});
        }
        while(!q.empty())
        {
            node now = q.top(); q.pop();
            int u = now.v;
            if(vis[u]) continue;
            vis[u] = true;
            for(int i = head[u]; ~i; i = edge[i].next)
            {
                int v = edge[i].v;
                int w = edge[i].w;
                di[v].push(dis[u] + w);
                if(di[v].size() > d[v] + 1) di[v].pop();
                if(di[v].top() < dis[v] && di[v].size() > d[v])
                {
                    dis[v] = di[v].top();
                    q.push((node){v, dis[v]});
                }
            }
        }
    }
    
    signed main()
    {
        ios;
        int T;
        cin >> T;
        while(T--)
        {
            cnt = 0;
            cin >> n >> m >> k;
            for(int i = 1;i <= n; i++)
            {
                dis[i] = inf;
                vis[i] = false;
                head[i] = -1;
                while(!di[i].empty()) di[i].pop();
            }
            for(int i = 0; i < k; i++) cin >> e[i];
            for(int i = 1; i <= n; i++) cin >> d[i];
            while(m--)
            {
                int u, v, w;
                cin >> u >> v >> w;
                add_edge(u, v, w);
            }
            dij();
            if(dis[1] == inf) cout << -1 << endl;
            else cout << dis[1] << endl;
        }
        return 0;
    }
  • 相关阅读:
    遗传算法
    模拟退火算法
    分支限界法(一)(转)
    (操作Excel 2007以後)Open XML SDK 2.0 for Microsoft Office
    c#接口和抽象类的区别
    抽象工厂模式
    乐在其中设计模式(C#)系列文章索引
    VB6.0 生成 XML方法
    处理一些简单的客户端脚本(2)
    抽象类
  • 原文地址:https://www.cnblogs.com/zyysyang/p/11262100.html
Copyright © 2020-2023  润新知