• [SDOI2010][最短路] 大陆争霸


    题面


    我们将每个节点的最短距离记录为如下两个量:(arr)(into),分别代表达到当前点的最短距离满足当前节点前置条件的最短距离,最短距离在两者中取大值。

    然后硬跑最短路就行了。

    代码:

    # include <iostream>
    # include <cstdio>
    # include <queue>
    # include <cstring>
    # define MAXN 300005
    # define MAXM 700005
    # define pii std::pair<int, int>
    # define mkp std::make_pair
    
    struct edge{
    	int v, next, w;
    }e[MAXM]; int hd[MAXN], cntE;
    struct node{
    	int to, next;
    }nd[MAXN]; int hdnd[MAXN], cntN;
    int degIn[MAXN], dis[MAXN]; bool vis[MAXN];
    int arr[MAXN], into[MAXN]; // 到达时间,可以进入的时间
    
    void AddE(int u, int v, int w){
    	e[++cntE] = (edge){v, hd[u], w};
    	hd[u] = cntE;
    }
    void AddN(int from, int to){
    	nd[++cntN] = (node){to, hdnd[from]};
    	hdnd[from] = cntN;
    }
    
    int main(){
    	int n, m;
    
    	scanf("%d%d", &n, &m);
    
    	for(int i = 1, u, v, w; i <= m; i++){
    		scanf("%d%d%d", &u, &v, &w);
    		AddE(u, v, w);
    	}
    
    	for(int i = 1, l, x; i <= n; i++){
    		scanf("%d", &l);
    		for(int j = 1; j <= l; j++){
    			scanf("%d", &x);
    			AddN(x, i); degIn[i]++;
    		}
    	}
    
    	std::priority_queue<pii, std::vector<pii>, std::greater<pii> >H;
    	memset(dis, 0x3f, sizeof(dis)); dis[1] = 0;
    	memset(arr, 0x3f, sizeof(arr)); arr[1] = 0;
    	// memset(into ,0x3f, sizeof(into)); into[1] = 0;
    	H.push(mkp(dis[1], 1)); // degIn[1] = 0;
    
    	while(H.size()){
    		// printf("FUCK
    ");
    		int now = H.top().second; H.pop();
    		if(!vis[now]){
    			vis[now] = true;
    			for(int i = hd[now]; i; i = e[i].next){
    				if(arr[e[i].v] > dis[now] + e[i].w){
    					arr[e[i].v] = dis[now] + e[i].w;
    					if(!degIn[e[i].v]){
    						dis[e[i].v] = std::max(arr[e[i].v], into[e[i].v]);
    						H.push(mkp(dis[e[i].v], e[i].v));
    					}
    				}
    			}
    			for(int i = hdnd[now]; i; i = nd[i].next){
    				into[nd[i].to] = std::max(into[nd[i].to], dis[now]);
    				degIn[nd[i].to]--;
    				if(!degIn[nd[i].to]){
    					dis[nd[i].to] = std::max(into[nd[i].to], arr[nd[i].to]);
    					H.push(mkp(dis[nd[i].to], nd[i].to));
    				}
    			}
    		}
    	}
    
    	printf("%d", dis[n]);
    
    	return 0;
    }
    
  • 相关阅读:
    工业设计之美
    狠挖用户需求与用户分析——赫志中
    《必然》
    在一周内学会使用 AUTO CAD
    可控硅调光知识总结
    PADS Logic Decal、Layout Decal绘制
    BUCK-BOOST反激变压器设计
    RCC BUCK-BOOST变压器设计
    产品生产
    由《旧制度与大革命》提取的5个感触
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13753576.html
Copyright © 2020-2023  润新知