zoukankan      html  css  js  c++  java
  • [题解] [bzoj2622] 深入虎穴

    题解

    题解

    考虑到正着跑不好想, 我们尝试反向跑

    以每个终点作为起点, 维护每个点的最小值和次小值(最小的被老虎ban掉了)

    转移的时候用当前点的次小值去更新其所连的点的最小值和次小值

    由于最小的次小值不能被其他次小值所更新, 所以我们可以使用dijkstra

    把每个终点丢进去跑dijkstra

    最后输出(1)的次小值即可

    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
    ", dis2[1]); 
    	return 0;
    } 
    
  • 相关阅读:
    课程作业一
    关于代码中的抄袭(不针对任何人)
    第四次作业
    第三次寒假作业-随笔汇总
    第三次寒假作业-合作
    第三次寒假作业-个人
    第二次寒假作业汇总
    问题
    第二次寒假作业——自学安排
    第二次寒假作业
  • 原文地址:https://www.cnblogs.com/ztlztl/p/11184687.html
Copyright © 2011-2022 走看看