题解

Kruskal重构树:每次一条边连接两个集合,建一个新点,点权为该边边权;把这两个集合的根连向新点。

性质:(如果求的是最大生成树)叶子结点是图中实际结点;叶子到根路径上点权递减;两点间lca的权值就是这两点走最大生成树经过的最小边

然后对于这题我们建重构树然后每次倍增找到一个深度极小的祖先u,返回u子树内实结点dis的最小值即可

#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 4e5 + 10;
const ll INF = 1e15;
int n, m, q, k, s;
struct Edge {
int v, w, nxt;
} e[N * 2];
int hd[N], c;
ll d[N];
void add(int u, int v, int w) {
e[c] = (Edge) {v, w, hd[u]}; hd[u] = c ++;
}
struct Node {
int u; ll d;
bool operator < (const Node &b) const { return d > b.d; }
};
void dijkstra() {
fill(d + 1, d + n + 1, INF); d[1] = 0;
priority_queue<Node> pq; pq.push((Node) {1, d[1]});
while(pq.size()) {
Node k = pq.top(); pq.pop();
if(d[k.u] < k.d) continue ;
for(int i = hd[k.u]; ~ i; i = e[i].nxt) {
if(d[e[i].v] > d[k.u] + e[i].w) {
pq.push((Node) {e[i].v, d[e[i].v] = d[k.u] + e[i].w});
}
}
}
}
struct Edge2 {
int u, v, w;
bool operator < (const Edge2 &e) const { return w > e.w; }
} e2[N];
int f[N], T[N], p[N][22], w[N], nn;
ll dt[N];
int find(int u) { return u == f[u] ? u : f[u] = find(f[u]); }
void kruskal() {
sort(e2 + 1, e2 + m + 1);
for(int i = 1; i <= n; i ++) f[i] = T[i] = i, dt[i] = d[i];
int cnt = 0; nn = n;
for(int i = 1; i <= m; i ++) {
int u = find(e2[i].u), v = find(e2[i].v);
if(u != v) {
p[T[u]][0] = p[T[v]][0] = ++ nn;
w[nn] = e2[i].w; p[nn][0] = 0;
dt[nn] = min(dt[T[u]], dt[T[v]]);
f[u] = v; T[v] = nn;
if(++ cnt == n - 1) break ;
}
}
for(int j = 1; j <= 20; j ++)
for(int i = 1; i <= nn; i ++)
p[i][j] = p[p[i][j - 1]][j - 1];
} ll qry(int u, int low) {
int v = u;
for(int i = 20; i >= 0; i --) {
if(p[v][i] && w[p[v][i]] > low) {
v = p[v][i];
}
}
return dt[v];
} void solve() {
scanf("%d%d", &n, &m);
fill(hd + 1, hd + n + 1, -1); c = 0;
for(int i = 1; i <= m; i ++) {
int u, v, l, h;
scanf("%d%d%d%d", &u, &v, &l, &h);
add(u, v, l); add(v, u, l);
e2[i] = (Edge2) {u, v, h};
}
dijkstra();
kruskal();
scanf("%d%d%d", &q, &k, &s);
ll lans = 0;
for(int i = 1; i <= q; i ++) {
int v, w; scanf("%d%d", &v, &w);
v = (v + k * lans - 1) % n + 1;
w = (w + k * lans) % (s + 1);
printf("%lld\n", lans = qry(v, w));
}
} int main() {
freopen("return.in", "r", stdin);
freopen("return.out", "w", stdout);
int T; scanf("%d", &T);
while(T --) solve();
fclose(stdin); fclose(stdout);
return 0;
}

「NOI 2018」归程「Kruskal 重构树」的更多相关文章

  1. 【NOI 2018】归程(Kruskal重构树)

    题面在这里就不放了. 同步赛在做这个题的时候,心里有点纠结,很容易想到离线的做法,将边和询问一起按水位线排序,模拟水位下降,维护当前的各个联通块中距离$1$最近的距离,每次遇到询问时输出所在联通块的信 ...

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

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

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

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

  4. NOI2018归程(Kruskal重构树)

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n). 我们依次用 l,a 描述一条边的长度. ...

  5. Luogu P4768 [NOI2018]归程(Dijkstra+Kruskal重构树)

    P4768 [NOI2018]归程 题面 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 \(n\) 个节点. \(m\) 条边的无向连通图(节点的编 ...

  6. 【BZOJ5415&UOJ393】归程(Kruskal重构树,最短路)

    题意:From https://www.cnblogs.com/Memory-of-winter/p/11628351.html 思路:先从1开始跑一遍dijkstra,建出kruskal重构树之后每 ...

  7. NOI2018 D1T1 洛谷P4768 归程 (Kruskal重构树)

    实际上是一个最短路问题,但加上了海拔这个条件限制,要在海拔<水位线p中找最短路. 这里使用Kruskal重构树,将其按海拔建成小根堆,我们就可以在树中用倍增找出他不得不下车的点:树中节点有两个权 ...

  8. NOI2018d1t1 归程 (dijkstra+kruskal重构树)

    题意:给一张无向联通图,每条边有长度和高度,每次询问在高度大于p的边,从v点能到达的所有点到1号点的最短距离(强制在线) 首先dijkstra求出每个点到1号点的距离 易知:如果我按高度从高到低给边排 ...

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

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

随机推荐

  1. vuex 理解

    为什么要用vuex?页面由多个视图组成,用户操作会引视图的状态变化. 多个视图依赖于同一状态(例如:菜单导航) 来自不同视图的行为需要变更同一状态(例如:评论弹幕) vuex 的作用 为vue.js开 ...

  2. canvas绘制文本自动换行

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  3. MySQL5.7主从从配置

    主从从,也称为级联主从,数据流向:A(主)->B(从)->C(从从),主从从级联复制. 应用场景 在主从配置的基础上,再增加一个从库,进一步提高数据安全,容灾备份. 读写分离,从库只用于查 ...

  4. 如何把Windows主机中的文件拉到centOS虚拟机中

    如何把Windows主机中的文件拉到centOS虚拟机中 2017年02月19日 22:19:12 Ariel_lin2017 阅读数:6023 标签: vmware tools共享文件   之前写了 ...

  5. HashSet和CopyOnWriteArraySet(转载)

    前言 这篇文章的目的如下: HashSet是如何保证元素的不重复和无序 HashSet的增删(改查?)原理 CopyOnWriteArraySet支持并发的原理 CopyOnWriteArraySet ...

  6. IO流的部分类简述

    InputStream 类: InputStream 位于 java.io 包中,它是一个抽象类,表示字节输入流,需要定义 InputStream 子类的应用程序必须总是提供返回下一个输入字节的方法 ...

  7. node - path路径

    1.node命令路径与js文件路径 node命令路径为node命令所执行的目录,js文件路径指的是你要运行的js所在的目录. 如上图所示: server.js路径为E:\zyp: node命令路径我们 ...

  8. 运动的border,仿当当简易效果

    突然想到以前看到当当上有个效果,当鼠标移上去,图片边框是运动添加上的,还以为是css3或者是canvas做的呢,做完幽灵按钮后,才知道,so  easy,只不过是animate+position的杰作 ...

  9. linux命令启动关闭firewalld防火墙,添加端口

    firewalld管理防火墙常用命令   1.查看防火墙的状态 [root@localhost HMK]# firewall-cmd --state 查看防火墙的运行状态 not running [r ...

  10. flask 中的ORM ( 二 )

    1 关系映射 1 多对多 1 什么是多对多 A表中的一条数据可以与B表中任意多条数据相关联 B表中的一条数据可以与A表中任意多条数据相关联 2 实现 在数据库中使用第三张表(关联表) 在编程语言中,可 ...