题目链接 \(Click\) \(Here\)

\(Kruskal\)重构树的好题。想到的话就很好写,想不到乱搞的难度反而相当高。

按照点的水位,建出来满足小根队性质的\(Kruskal\)重构树,这样一个点的子树里的点就是所有可以开车到达的点。做一遍最短路预处理,然后树上求一个子树\(min\),就可以得到子树里面的点到点\(1\)的最短距离。注意需要初始化。

#include <bits/stdc++.h>
using namespace std; const int N = 800010;
const int INF = 0x7fffffff; struct _edge {int u, v, l, a;}_e[N]; bool cmp (_edge lhs, _edge rhs) {
return lhs.a > rhs.a;
} struct Graph {
int cnt, head[N]; struct edge {
int nxt, to, w;
}e[N << 1]; void Init () {
cnt = 0;
memset (head, 0, sizeof (head));
} void add_edge (int u, int v, int w) {
e[++cnt] = (edge) {head[u], v, w}; head[u] = cnt;
}
}G, krus; int read () {
int s = 0, w = 1, ch = getchar ();
while ('9' < ch || ch < '0') {
if (ch == '-') w = -1;
ch = getchar ();
}
while ('0' <= ch && ch <= '9') {
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * w;
} int T, n, m, Q, K, S, tot, fa[N], _high[N]; int find (int x) {
return fa[x] == x ? x : fa[x] = find (fa[x]);
} int deep[N], fafa[N][20]; int dis[N], mindis[N]; void dfs (int u, int fa) {
fafa[u][0] = fa;
mindis[u] = krus.head[u] == 0 ? dis[u] : INF;
deep[u] = deep[fa] + 1;
for (int i = 1; (1 << i) <= deep[u]; ++i) {
fafa[u][i] = fafa[fafa[u][i - 1]][i - 1];
}
for (int i = krus.head[u]; i; i = krus.e[i].nxt) {
int v = krus.e[i].to;
dfs (v, u);
mindis[u] = min (mindis[u], mindis[v]);
}
} void kruskal () {
sort (_e + 1, _e + 1 + m, cmp);
tot = n;
for (int i = 1; i <= n; ++i) fa[i] = i;
for (int i = 1; i <= m; ++i) {
int u = find (_e[i].u);
int v = find (_e[i].v);
if (u != v) {
int T = ++tot;
_high[T] = _e[i].a;
krus.add_edge (T, u, 0);
krus.add_edge (T, v, 0);
fa[T] = fa[u] = fa[v] = T;
}
}
dfs (tot, 0);
} struct Node {
int pos, dis; bool operator < (Node rhs) const {
return dis > rhs.dis;
}
}; priority_queue <Node> q; void dijkstra () {
for (int i = 1; i <= n; ++i) dis[i] = i == 1 ? 0 : INF;
q.push ((Node) {1, 0});
while (!q.empty ()) {
Node u = q.top (); q.pop ();
if (dis[u.pos] < u.dis) continue;
for (int i = G.head[u.pos]; i; i = G.e[i].nxt) {
int v = G.e[i].to;
if (dis[v] > dis[u.pos] + G.e[i].w) {
dis[v] = dis[u.pos] + G.e[i].w;
q.push ((Node) {v, dis[v]});
}
}
}
} int query (int u, int p) {
//u 出发节点 p 水位线
for (int i = 19; i >= 0; --i) {
if (_high[fafa[u][i]] > p) {
u = fafa[u][i];
}
}
// printf ("u = %d\n", u);
return mindis[u];
} void Init () {
G.Init ();
krus.Init ();
memset (fafa, 0, sizeof (fafa));
memset (_high, 0, sizeof (_high));
memset (mindis, 0, sizeof (mindis));
} int main () {
//freopen ("data.in", "r", stdin);
T = read ();
while (T--) {
Init ();
printf ("T = %d\n", T);
n = read (), m = read ();
for (int i = 1; i <= m; ++i) {
_e[i].u = read ();
_e[i].v = read ();
_e[i].l = read ();
_e[i].a = read ();
G.add_edge (_e[i].u, _e[i].v, _e[i].l);
G.add_edge (_e[i].v, _e[i].u, _e[i].l); //建双向边
}
int lastans = 0;
dijkstra ();
kruskal ();
Q = read (), K = read (), S = read ();
for (int i = 1; i <= Q; ++i) {
static int v, p, v0, p0;
v0 = read (), p0 = read ();
v = (v0 + K * lastans - 1) % n + 1;
p = (p0 + K * lastans) % (S + 1);
printf ("%d\n", lastans = query (v, p));
}
}
}

Luogu P4768 [NOI2018]归程的更多相关文章

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

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

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

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

  3. [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)

    洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...

  4. 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]

    题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...

  5. P4768 [NOI2018]归程

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

  6. 洛谷P4768 [NOI2018]归程(Kruskal重构树)

    题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...

  7. 洛谷P4768 [NOI2018]归程(可持久化并查集,最短路)

    闲话 一个蒟蒻,在网络同步赛上进行了这样的表演-- T2组合计数不会,T3字符串数据结构不会,于是爆肝T1 一开始以为整个地图都有车,然后写了2h+的树套树,终于发现样例过不去 然后写可持久化并查集D ...

  8. 洛谷 P4768 [NOI2018]归程

    洛谷 361行代码的由来 数据分治大发好啊- NOI的签到题,可怜我在家打了一下午才搞了80分. 正解应该是kruskal重构树或排序+可持久化并查集. 我就分点来讲暴力80分做法吧(毕竟正解我也没太 ...

  9. Luogu 4768 [NOI2018]归程

    并不会写Kruskal重构树,两个$log$跑得比较卡. 首先考虑一下没有强制在线的要求怎么办,有一个比较容易想到的做法就是先跑一遍最短路,然后把所有边按照海拔从大到小排序,把所有询问的海拔也从大到小 ...

随机推荐

  1. Redux 学习(1) ----- Redux介绍

    Redux 有三个基本的原则: 1,单一状态树,redux 只使用一个javascript 对象来保存整个应用的状态. 状态树样式如下: const state = { count: 0 } 2,状态 ...

  2. Xtoken

    “我希望有一种模式,利用群体的智慧让最好的想法总能够脱颖而出”. 博弈模型 背景 本文为NEO社区理事会秘书长陶荣祺在全球创业周区块链创新与发展论坛上的主题演讲<Xtoken代观社区驱动群体智慧 ...

  3. 二、Java多人博客系统-演变

    任何项目都是由小到大,逐步演变的.自己写的这个博客系统也不例外. 更新日志如下: 一.2014年底-2015年初 功能及技术: 1.定位为个人网站,介绍自己情况和发布文章等. 2.首页模块有:个人简介 ...

  4. JarvisOJ Basic 爱吃培根的出题人

    听说你也喜欢吃培根?那我们一起来欣赏一段培根的介绍吧: bacoN is one of aMerICa'S sWEethEartS. it's A dARlinG, SuCCulEnt fOoD tH ...

  5. Cent OS安装使用ffmpeg(完整版)

    Cent OS安装使用ffmpeg centos作为主流后台linux 系统,ffmpeg作为视频流解析的主力,尤其是ffmpeg配合opencv使用,则是视觉操作的基础 版本: ffmpeg3.1 ...

  6. DrawableAnimation小练习

    DrawableAnimation,也就是帧动画,将图片一张张显示出来,从而形成动画的效果 先在项目文件夹下新建一个目录drawable,然后在里面新建一个xml文件,自定义文件名,我的叫my_ani ...

  7. 【XSY1580】Y队列 容斥

    题目大意 给你\(n,r\),求第\(n\)个不能被表示为\(a^b(2\leq b\leq r)\)的数 \(n\leq 2\times {10}^{18},r\leq 62\) 题解 我们考虑二分 ...

  8. PHP 公共方法分享180628

    查看php 类的详情:方法.常量.属性( type(new \Illuminate\Http\Request());) /** * fixme 打印类详情 * @param $class object ...

  9. php 排序数组array_multisort

    $arr[] = array('name'=>'a','flag'=>1); $arr[] = array('name'=>'b','flag'=>2); $arr[] = a ...

  10. Qt Creator 搭配Git 版本控制

    再次介绍一下Git的使用,这次是在Coding.net上部署项目的.这个是写给大作业合作的小伙伴们(我和我的A奶朋友们和某A的男朋友)看的. 安装Git 首先安装Git(msysGit) 下载地址 h ...