[Explanations] [bzoj2622] Cronicas

answer

answer

Taking into account the positive with running a bad thought, we try to reverse run

At each end as a starting point, minimum maintenance and sub-minimum value of each point (the smallest tiger ban is off)

Minimum and sub-minimum value when transfer times with a small value of the current point to update it even point

Since the minimum of the next smallest value can not be updated other times small value, so we can use dijkstra

Throw into the end of each run dijkstra

Final output \ (1 \) is the second smallest value to

Code

#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;
} 

Guess you like

Origin www.cnblogs.com/ztlztl/p/11184687.html