#Kruskal重构树,Dijkstra,倍增#洛谷 4768 [NOI2018]归程
分析
首先Dijkstra是必需的(关于SPFA,它死了233)
无向图,所以先求出1号节点到所有点的距离,然后肯定希望起点能驾驶到离一号点最短的汽车可到的地方
但是怎么办,考虑海拔大的边肯定会更想选,那为什么不用Kruskal建出一棵最大生成树
但是怎么求呢,Kruskal重构树横空出世,通过用新点连接原来两点,建起一棵\(2n-1\)个点的树
那有什么用呢,这棵树变成了二叉堆,在本题中还是小根堆,也就是两点LCA代表了重构树路径上最小边
那边再求个最小值不就可以用倍增解决了吗
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define rr register
using namespace std;
const int N=400011;
struct rec{int x,y,w,c;}T[N]; struct node{int y,w,next;}e[N<<1]; struct Node{int y,next;}E[N];
int ls[N>>1],hs[N],dis[N],h[N],dep[N],n,m,k,K,cnt,nnt,f[N][20],Q,opt,S,fat[N]; pair<int,int>heap[N>>1];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
return ans;
}
inline void add(int x,int y,int w){e[++k]=(node){y,w,ls[x]}; ls[x]=k;}
inline void Add(int x,int y){E[++K]=(Node){y,hs[x]},hs[x]=K;}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline void Push(pair<int,int>w){
heap[++cnt]=w;
rr int x=cnt;
while (x>1){
if (heap[x>>1]>heap[x])
swap(heap[x>>1],heap[x]),x>>=1;
else return;
}
}
inline void Pop(){
heap[1]=heap[cnt--];
rr int x=1;
while ((x<<1)<=cnt){
rr int y=x<<1;
if (y<cnt&&heap[y+1]<heap[y]) ++y;
if (heap[y]<heap[x]) swap(heap[y],heap[x]),x=y;
else return;
}
}
inline void Dijkstra(){
dis[1]=0,heap[++cnt]=make_pair(0,1);
while (cnt){
rr int x=heap[1].second,t=heap[1].first;
Pop(); if (t!=dis[x]) continue;
for (rr int i=ls[x];i;i=e[i].next)
if (dis[e[i].y]>dis[x]+e[i].w){
dis[e[i].y]=dis[x]+e[i].w;
Push(make_pair(dis[e[i].y],e[i].y));
}
}
}
bool cmp(rec x,rec y){return x.c>y.c;}
inline signed getf(int u){return fat[u]==u?u:fat[u]=getf(fat[u]);}
inline void Kruskal(){
for (rr int i=1;i<n*2;++i) fat[i]=i;
for (rr int i=1,tot=0;i<=m;++i){
rr int fa=getf(T[i].x),fb=getf(T[i].y);
if (fa!=fb){
fat[fa]=fat[fb]=++nnt,h[nnt]=T[i].c;
Add(nnt,fa),Add(nnt,fb);
if (++tot==n-1) return;
}
}
}
inline void dfs(int x,int fa){
dep[x]=dep[fa]+1,f[x][0]=fa;
for (rr int i=1;i<20;++i) f[x][i]=f[f[x][i-1]][i-1];
for (rr int i=hs[x];i;i=E[i].next)
dfs(E[i].y,x),dis[x]=min(dis[x],dis[E[i].y]);
}
inline signed GetF(int x,int H){
for (rr int i=19;~i;--i)
if (dep[x]>=(1<<i)&&h[f[x][i]]>H) x=f[x][i];
return dis[x];
}
signed main(){
for (rr int Test=iut();Test;--Test){
memset(ls,0,sizeof(ls)),memset(f,0,sizeof(f));
memset(dep,0,sizeof(dep)),memset(hs,0,sizeof(hs));
memset(h,0,sizeof(h)),memset(dis,0x3f,sizeof(dis));
n=iut(),m=iut(),k=K=1,nnt=n;
for (rr int i=1;i<=m;++i){
T[i]=(rec){iut(),iut(),iut(),iut()};
add(T[i].x,T[i].y,T[i].w);
add(T[i].y,T[i].x,T[i].w);
}
Dijkstra(),sort(T+1,T+1+m,cmp),Kruskal(),
dfs(nnt,0),Q=iut(),opt=iut(),S=iut();
for (rr int lastans=0;Q;Q--){
rr int G=iut(),H=iut();
if (opt) G=(G+lastans-1)%n+1,H=(H+lastans)%(S+1);
print(lastans=GetF(G,H)),putchar(10);
}
}
return 0;
}
#Kruskal重构树,Dijkstra,倍增#洛谷 4768 [NOI2018]归程的更多相关文章
- NOI Day1T1归程(Kruskal重构树+Dijkstra)
NOI Day1T1归程(Kruskal重构树+Dijkstra) 题目 洛谷题目传送门 题解 其实我不想写......,所以...... 挖个坑......我以后一定会补的 luogu的题解讲的还是 ...
- [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)
洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...
- 洛谷P4768 [NOI2018]归程(Kruskal重构树)
题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...
- UVA1265 Tour Belt Kruskal重构树、倍增、树上差分
题目传送门 题意:定义$Tour \, Belt$为某张图上的一个满足以下条件的点集:①点集中至少有$2$个点②任意两点互相连通③图上两个端点都在这个点集中的边的权值的最小值严格大于图上只有一个端点在 ...
- 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树
这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...
- 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]
题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...
- 洛谷 P4768 [NOI2018]归程
洛谷 361行代码的由来 数据分治大发好啊- NOI的签到题,可怜我在家打了一下午才搞了80分. 正解应该是kruskal重构树或排序+可持久化并查集. 我就分点来讲暴力80分做法吧(毕竟正解我也没太 ...
- 洛谷P4768 [NOI2018]归程(克鲁斯卡尔重构树+最短路)
传送门 前置技能,克鲁斯卡尔重构树 我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树 那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价) 可以一开始直接 ...
- 洛谷$P4768\ [NOI2018]$归程 $kruscal$重构树
正解:$kruscal$重构树 解题报告: 传送门$QwQ$ 语文不好选手没有人权$TT$连题目都看不懂真的要哭了$kk$ 所以先放个题目大意?就说给定一个$n$个点,$m$条边的图,每条边有长度和海 ...
- 洛谷P4768 [NOI2018]归程(可持久化并查集,最短路)
闲话 一个蒟蒻,在网络同步赛上进行了这样的表演-- T2组合计数不会,T3字符串数据结构不会,于是爆肝T1 一开始以为整个地图都有车,然后写了2h+的树套树,终于发现样例过不去 然后写可持久化并查集D ...
随机推荐
- RHEL8重置root用户密码步骤
要先确定是否为RHEL 8系统. [root@zhangsan ~]# cat /etc/redhat-release Red Hat Enterprise Linux release 8.0 (Oo ...
- pika
生产者代码 # -*- coding: utf-8 -*- # pylint: disable=C0111,C0103,R0205 import json import pika from pika. ...
- C#多线程(7):手动线程通知
目录 区别与示例 ManualResetEvent 类 ManualResetEventSlim 区别与示例 AutoResetEvent 和 ManualResetEvent 十分相似.两者之间的区 ...
- RocketMQ(6) offset管理
这里的offset指的是Consumer的消费进度offset. 消费进度offset是用来记录每个Queue的不同消费组的消费进度的.根据消费进度记录器的不同,可以分为两种模式:本地模式和远程模式. ...
- 2.UML类图基本介绍
1. UML 基本介绍 UML--Unified modeling language UML(统一建模语言),是一种用于软件系统分析和设计的语言工具,它用于帮助软件开发人员进行思考和记录思路的结果 U ...
- mockjs 前端写完 给后台调 mock.js | 改到2.0版本
需求:最近活太忙了,实在是联调没有时间了,无奈又拾起来mockjs 1 安装mockjs npm install mockjs // 这是个只在开发的时候用,打包后就没有了,业务更安全 npm ins ...
- java学习 javaz-001 Helloworld 第一个demo
java学习 javaz-001 Helloworld 第一个demo 目录 学习目标 前期准备 java sdk 1.8环境 编辑器IDE的选择 代码开发 目录结构 创建第一个java文件 创建第2 ...
- 使用systemback工具制定Debian.ISO文件
1.安装systemback https://nchc.dl.sourceforge.net/project/systemback/1.8/Systemback_Install_Pack_v1.8.4 ...
- BES2500开发板介绍和入门
一 前记 BES2500是恒玄科技推出的款高端的TWS耳机芯片,该芯片的性能非常强悍.蓝牙5.2双模,1.8M的SRAM空间,ARM-M33的主核,绝对是音频耳机芯片中的高配,性能不是一般的强.该芯片 ...
- Python爬虫实战系列2:虎嗅网24小时热门新闻采集
一.分析页面 打开虎嗅网,点击[24小时] 本次采集,我们以这24小时的热门新闻为案例. 1.1.分析请求 F12打开开发者模式,然后点击Network后点击任意一个请求,Ctrl+F开启搜索,输入标 ...