zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    怎样跟踪来访用户?
    五个瓶颈影响你的Asp.Net程序(网站)性能
    if判断与比较操作符gt、lt、eq等的使用
    裸机LCD驱动配置
    汇编指令-位置无关码(BL)与绝对位置码(LDR)(2)
    汇编指令-MRS(读)和MSR(写)指令操作CPSR寄存器和SPSR寄存器使用(1)
    Nand Flash驱动(实现初始化以及读操作)
    makefile使用.lds链接脚本以及 $@ ,$^, $,< 解析
    makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解
    Liunx-常用命令杂烩(5)
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13753576.html
Copyright © 2011-2022 走看看