传送门

题意:给出一个$N$个点、$M$条边的图,每条边有长度和海拔,$Q$组询问,每一次询问从$v$开始,经过海拔超过$p$的边所能到达的所有点中到点$1$的最短路的最小值,强制在线。$N \leq 2 \times 10^5 , M , Q \leq 4 \times 10^5$


关于$SPFA...$

与边的权值有关的连通块问题,经常可以考虑到$Kruskal$重构树。我们以海拔从大到小构建$Kruskal$重构树,那么对于每一次询问,可以到达的点就对应$Kruskal$重构树上的一棵子树。我们对于每一个点记录它的子树的叶子节点的最短路的最小值,每一次倍增找到询问对应的那一棵子树就能得到答案了。

#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;

inline int read(){
    ;
    ;
    char c = getchar();
    while(c != EOF && !isdigit(c)){
        if(c == '-')
            f = ;
        c = getchar();
    }
    while(c != EOF && isdigit(c)){
        a = (a << ) + (a << ) + (c ^ ');
        c = getchar();
    }
    return f ? -a : a;
}

;
struct edge{
    int start , end , hei;
}now[MAXN];
struct Edge{
    int end , upEd , w;
}Ed[MAXN << ];
] , jump[MAXN << ][] , val[MAXN << ] , ans[MAXN << ] , ch[MAXN << ][] , cntNode , cntEd , N , M , Q;
priority_queue < pair < int , int > > q;

bool operator <(edge a , edge b){
    return a.hei > b.hei;
}

int find(int a){
    return fa[a] == a ? a : (fa[a] = find(fa[a]));
}

inline void addEd(int a , int b , int c){
    Ed[++cntEd].end = b;
    Ed[cntEd].upEd = head[a];
    Ed[cntEd].w = c;
    head[a] = cntEd;
}

void Dijk(){
    memset(minDis , 0x7f , sizeof(minDis));
    minDis[] = ;
    q.push(make_pair( , ));
    while(!q.empty()){
        pair < int , int > t = q.top();
        q.pop();
        if(-t.first > minDis[t.second])
            continue;
        for(int i = head[t.second] ; i ; i = Ed[i].upEd)
            if(minDis[Ed[i].end] > minDis[t.second] + Ed[i].w){
                minDis[Ed[i].end] = minDis[t.second] + Ed[i].w;
                q.push(make_pair(-minDis[Ed[i].end] , Ed[i].end));
            }
    }
}

void dfs(int node){
    if(!node)
        return;
     ; i <=  && jump[node][i - ] ; ++i)
        jump[node][i] = jump[jump[node][i - ]][i - ];
    dfs(ch[node][]);
    dfs(ch[node][]);
}

inline int jumpToAll(int x , int h){
     ; i >=  ; --i)
        if(val[jump[x][i]] > h)
            x = jump[x][i];
    return x;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("4768.in" , "r" , stdin);
    //freopen("4768.out" , "w" , stdout);
#endif
    for(int T = read() ; T ; --T){
        memset(jump ,  , sizeof(jump));
        memset(ch ,  , sizeof(ch));
        memset(head ,  , sizeof(head));
        cntEd = ;
        N = read();
        M = read();
         ; i <= M ; i++){
            int a = read() , b = read() , c = read() , d = read();
            now[i].start = a;
            now[i].end = b;
            now[i].hei = d;
            addEd(a , b , c);
            addEd(b , a , c);
        }
        Dijk();
         ; i <= N ; i++){
            fa[i] = i;
            ans[i] = minDis[i];
        }
        sort(now +  , now + M + );
        cntNode = N;
         ; i <= M ; ++i)
            if(find(now[i].start) != find(now[i].end)){
                int a = find(now[i].start) , b = find(now[i].end);
                fa[a] = fa[b] = jump[a][] = jump[b][] = ++cntNode;
                ch[cntNode][] = a;
                ch[cntNode][] = b;
                val[cntNode] = now[i].hei;
                ans[cntNode] = min(ans[a] , ans[b]);
                fa[cntNode] = cntNode;
            }
        dfs(cntNode);
         , Q = read() , K = read() , S = read();
        while(Q--){
            int a = read() , b = read();
            a = (0ll + a + K * lastans - ) % N + ;
            b = (0ll + b + K * lastans) % (S + );
            int t = jumpToAll(a , b);
            printf("%d\n" , lastans = ans[t]);
        }
    }
    ;
}

Luogu4768 NOI2018 归程 最短路、Kruskal重构树的更多相关文章

  1. Luogu4768 NOI2018归程(最短路径+kruskal重构树)

    按海拔从大到小合并建出kruskal重构树,这样就能知道开车能到达哪些点,对这些点到1的最短路取min即可.最难的部分在于多组数据的初始化和数组大小的设置. #include<iostream& ...

  2. 【NOI2018】归程 题解(kruskal重构树+最短路)

    题目链接 题目大意:给定一张$n$个点$m$条边的无向图.每条边有长度和海拔.有$Q$次询问,每次给定起点$v$和当天水位线$p$,每次终点都是$1$.人可以选择坐车或走路,车只能在海拔大于水位线的路 ...

  3. LOJ #2718. 「NOI2018」归程(Dijkstra + Kruskal重构树 + 倍增)

    题意 给你一个无向图,其中每条边有两个值 \(l, a\) 代表一条边的长度和海拔. 其中有 \(q\) 次询问(强制在线),每次询问给你两个参数 \(v, p\) ,表示在 \(v\) 出发,能开车 ...

  4. 洛谷P4768 [NOI2018]归程(克鲁斯卡尔重构树+最短路)

    传送门 前置技能,克鲁斯卡尔重构树 我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树 那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价) 可以一开始直接 ...

  5. [NOI2018]归程 kruskal重构树

    [NOI2018]归程 LG传送门 kruskal重构树模板题. 另一篇文章里有关于kruskal重构树更详细的介绍和更板子的题目. 题意懒得说了,这题的关键在于快速找出从查询的点出发能到达的点(即经 ...

  6. P4768 [NOI2018]归程(kruskal 重构树)

    洛谷P4768 [NOI2018]归程 LOJ#2718.「NOI2018」归程 用到 kruskal 重构树,所以先说这是个啥 显然,这和 kruskal 算法有关系 (废话 这个重构树是一个有点权 ...

  7. [学习笔记]kruskal重构树 && 并查集重构树

    Kruskal 重构树 [您有新的未分配科技点][BZOJ3545&BZOJ3551]克鲁斯卡尔重构树 kruskal是一个性质优秀的算法 加入的边是越来越劣的 科学家们借这个特点尝试搞一点事 ...

  8. BZOJ 4242: 水壶(Kruskal重构树 + Bfs)

    题意 一块 \(h ∗ w\) 的区域,存在障碍.空地.\(n\) 个建筑,从一个建筑到另一个建筑的花费为:路径上最长的连续空地的长度. \(q\) 次询问:从建筑 \(s_i\) 到 \(t_i\) ...

  9. [luogu4768] [NOI2018] 归程 (Dijkstra+Kruskal重构树)

    [luogu4768] [NOI2018] 归程 (Dijkstra+Kruskal重构树) 题面 题面较长,这里就不贴了 分析 看到不能经过有积水的边,即不能经过边权小于一定值的边,我们想到了kru ...

随机推荐

  1. MVC与单元测试实践之健身网站(六)-计划的添加与重置

    健身计划需要使用者自己定制,没有现成的内容可供选择.本篇就是关于健身计划的添加与重置功能的一部分. 一 功能描述 a) 关于计划的定制,决定以周期的方式,比如有人会以一周为周期,然后安排每周的1.3. ...

  2. (其他)最常用的15大Eclipse开发快捷键技巧

    转自CSDNJava我人生(陈磊兴)   原文出处 引言 做java开发的,经常会用Eclipse或者MyEclise集成开发环境,一些实用的Eclipse快捷键和使用技巧,可以在平常开发中节约出很多 ...

  3. CSS3创建圆圈进度条

    最近在工作中需要做一个圆圈倒计时,刚开始的想法是做个纯数字的倒计时即可,可是需求觉得这个不太好看,想加个倒计时进度条.于是就有了接下来的分析过程... 我们知道CSS3可以很方便的画圆,圆环,然后在加 ...

  4. kNN处理iris数据集-使用交叉验证方法确定最优 k 值

    基本流程: 1.计算测试实例到所有训练集实例的距离: 2.对所有的距离进行排序,找到k个最近的邻居: 3.对k个近邻对应的结果进行合并,再排序,返回出现次数最多的那个结果. 交叉验证: 对每一个k,使 ...

  5. [20170914]tnsnames.ora的管理.txt

    [20170914]tnsnames.ora的管理.txt --//昨天朋友讲tnsnams.ora的内容太长了,而且许多不需要的.管理不方便.我记得以前写[20150409]tnsnames.ora ...

  6. 转:Vue2.0+组件库总结

    UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组件库 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开 ...

  7. 將UNITY作品上傳到Facebook App!

    前言 大家好,今天要來介紹如何用UNITY 將製作好的遊戲上傳到Facebook,也就是Facebook App.近期Facebook與Unity合作而推出了新的插件,利用插件可上傳分數.邀請好友.P ...

  8. 基于LNMP(fastcgi协议)环境部署、原理介绍以及fastcgi_cache配置以及upstream模块负载均衡讲解

    ngx_http_proxy_module只能反向代理后端使用HTTP协议的主机.而ngx_http_fastcgi_module只能反向代理后端使用FPM或者使用FastCGI协议的客户端. 一.部 ...

  9. Linux防火墙基础与编写防火墙规则

    Iptables采用了表和链的分层结构,每个规则表相当于内核空间的一个容器,根据规则集的不同用途划分为默认的四个表,raw表,mangle表,nat表,filter表,每个表容器内包括不同的规则链,根 ...

  10. 16LaTeX学习系列之---LaTeX数学公式的补充

    目录 目录 前言 (一)知识点说明 1.基础细节 2.gather环境 3.align环境 4.split环境 5.cases环境 (二)实例 1.源代码 2.输出效果 目录 本系列是有关LaTeX的 ...