[説明] [bzoj2622] Cronicas

問題の解決策

問題の解決策

悪い考えを実行すると、正考慮すると、我々は実行を逆にしてみてください

出発点、最小メンテナンス及び各点のサブ最小値(最小トラ禁止がオフになっている)のような各端部

現在のポイントの小さい値と転送回数が偶数点を更新する最小サブ最小値

次に小さい値の最小値が、他の回小さな値を更新することはできませんので、私たちはダイクストラを使用することができます

各実行ダイクストラの最後に投げます

最終出力\(1 \)は、第2の最小値であります

コード

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#define itn int
#define reaD read
#define mp(x,y) make_pair(1ll*x,y)
#define N 200005
using namespace std;

int n, m, k, head[N], cnt; 
struct edge { int to, next, cost; } e[N << 5]; 
bool vis[N];
long long dis1[N], dis2[N]; 

namespace Heap
{
    pair<long long, int> heap[N << 2]; int sz = 0; 
    void push(pair <int, int> x) { x.first *= -1; heap[++sz] = x; push_heap(heap + 1, heap + sz + 1); }
    void pop() { pop_heap(heap + 1, heap + sz + 1); sz--; }
    pair<int, int> top() { pair<int, int> tmp; tmp = heap[1]; tmp.first *= -1; return tmp; }
    bool empty() { return !sz; }
}; 

using namespace :: Heap; 

inline int read()
{
    int x = 0, w = 1; char c = getchar();
    while(c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    return x * w;
}

inline void adde(int u, int v, int w) { e[++cnt] = (edge) { v, head[u], w }; head[u] = cnt; }

void dijkstra()
{
    while(!empty())
    {
        int u = top().second; pop();
        if(vis[u]) continue; vis[u] = 1;
        for(int i = head[u]; i; i = e[i].next)
        {
            int v = e[i].to;
            long long sum = dis2[u] + e[i].cost;
            if(sum < dis2[v])
            {
                if(sum < dis1[v]) dis2[v] = dis1[v], dis1[v] = sum;
                else dis2[v] = sum; 
            }
            if(dis2[v] < dis1[0] && !vis[v]) push(mp(dis2[v], v)); 
        }
    }
}

int main()
{
    n = read(); m = read(); k = read();
    for(int i = 1; i <= m; i++)
    {
        itn u = read() + 1, v = read() + 1, w = read();
        adde(u, v, w); adde(v, u, w); 
    }
    memset(dis1, 0x3f, sizeof(dis1)); 
    memset(dis2, 0x3f, sizeof(dis2));
    for(int i = 1; i <= k; i++)
    {
        int x = reaD();
        dis1[x + 1] = dis2[x + 1] = 0;
        push(mp(dis2[x + 1], x + 1)); 
    }
    dijkstra(); 
    printf("%lld\n", dis2[1]); 
    return 0;
} 

おすすめ

転載: www.cnblogs.com/ztlztl/p/11184687.html