BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增+最短路
BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增
Description
www.lydsy.com/JudgeOnline/upload/noi2018day1.pdf
好久不写题解了,趁着周末都更一下吧。
处理出以1为起点的最短路dis。
考虑每次只能走海拔大于p的边,用kruscal重构树维护一个以海拔为关键字的最大生成树。
这样我们每次能走的连通块就是一个重构树中的一个子树。
倍增找一下是哪棵子树,子树取dis的最小值即可。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace std;
#define N 400050
#define M 400050
#define inf 2147483647
typedef long long ll;
__attribute__((optimize("-O3")))inline char nc() {
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
__attribute__((optimize("-O3")))int rd() {
int x=0; char s=nc();
while(s<'0'||s>'9') s=nc();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
return x;
}
char pbuf[100000],*pp=pbuf;
__attribute__((optimize("-O3")))void push(const char c) {
if(pp-pbuf==100000) fwrite(pbuf,1,100000,stdout),pp=pbuf;
*pp++=c;
}
__attribute__((optimize("-O3")))void write(int x) {
static int sta[35];
int top=0;
do{sta[top++]=x%10,x/=10;}while(x);
while(top) push(sta[--top]+'0');
}
int head[N],to[M<<1],nxt[M<<1],cnt,f[23][N],mn[N],val[M<<1],n,m,dis[N],vis[N],Lg[N];
int fa[N],w[N];
int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
struct E {
int x,y,z,w;
bool operator < (const E &u) const {
return w>u.w;
}
}e[M];
__gnu_pbds::priority_queue<pair<int,int> >q;
__attribute__((optimize("-O3")))inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
__attribute__((optimize("-O3")))void add(int u,int v,int w) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
}
__attribute__((optimize("-O3")))void dij() {
int i;
for(i=1;i<=n;i++) dis[i]=2147483647;
dis[1]=0;
memset(vis,0,sizeof(vis));
q.push(make_pair(0,1));
while(!q.empty()) {
int x=q.top().second,i; q.pop();
if(vis[x]) continue;
vis[x]=1;
if(dis[x]==inf) continue;
for(i=head[x];i;i=nxt[i]) {
if(dis[to[i]]>dis[x]+val[i]) {
dis[to[i]]=dis[x]+val[i];
q.push(make_pair(-dis[to[i]],to[i]));
}
}
}
}
__attribute__((optimize("-O3")))void dfs(int x) {
int i;
if(x<=n) mn[x]=dis[x];
else mn[x]=inf;
for(i=head[x];i;i=nxt[i]) {
f[0][to[i]]=x;
dfs(to[i]);
mn[x]=min(mn[x],mn[to[i]]);
}
}
__attribute__((optimize("-O3")))void solve() {
memset(head,0,sizeof(head)); cnt=0;
memset(f,0,sizeof(f));
n=rd(); m=rd();
int i,x,y,j;
for(i=1;i<=m;i++) {
e[i].x=rd(); e[i].y=rd(); e[i].z=rd(); e[i].w=rd(); add(e[i].x,e[i].y,e[i].z); add(e[i].y,e[i].x,e[i].z);
}
dij();
memset(head,0,sizeof(head)); cnt=0;
sort(e+1,e+m+1);
for(Lg[0]=-1,i=1;i<=2*n;i++) fa[i]=i,Lg[i]=Lg[i>>1]+1;
int tot=n;
for(i=1;i<=m;i++) {
int dx=find(e[i].x),dy=find(e[i].y);
if(dx==dy) continue;
tot++; fa[dx]=tot; fa[dy]=tot; add(tot,dx); add(tot,dy); w[tot]=e[i].w;
}
dfs(tot);
for(i=1;(1<<i)<=tot;i++) {
for(j=1;j<=tot;j++) {
f[i][j]=f[i-1][f[i-1][j]];
}
}
int opt,cas,S;
cas=rd(); opt=rd(); S=rd();
int ans=0;
while(cas--) {
x=rd(); y=rd();
x=(ll(x)+opt*ans-1)%n+1;
y=(ll(y)+opt*ans)%(S+1);
for(i=Lg[tot];i>=0;i--) {
if(!f[i][x]) continue;
if(w[f[i][x]]>y) x=f[i][x];
}
ans=mn[x];
write(ans); push('\n');
}
}
__attribute__((optimize("-O3")))int main() {
// freopen("return.in","r",stdin);
// freopen("return.out","w",stdout);
int T;
T=rd();
while(T--) solve();
fwrite(pbuf,1,pp-pbuf,stdout);
}
BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增+最短路的更多相关文章
- BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra
题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...
- LOJ.2718.[NOI2018]归程(Kruskal重构树 倍增)
LOJ2718 BZOJ5415 洛谷P4768 Rank3+Rank1无压力 BZOJ最初还不是一道权限题... Update 2019.1.5 UOJ上被hack了....好像是纯一条链的数据过不 ...
- [NOI2018]归程 kruskal重构树
[NOI2018]归程 LG传送门 kruskal重构树模板题. 另一篇文章里有关于kruskal重构树更详细的介绍和更板子的题目. 题意懒得说了,这题的关键在于快速找出从查询的点出发能到达的点(即经 ...
- [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)
洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...
- 洛谷P4768 [NOI2018]归程(Kruskal重构树)
题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...
- BZOJ 5415: [Noi2018]归程(kruskal重构树)
解题思路 \(NOI2018\)的\(Day1\) \(T1\),当时打网络赛的时候不会做.学了一下\(kruskal\)重构树后发现问题迎刃而解了.根据\(kruskal\)的性质,如果要找从\(u ...
- 洛谷$P4768\ [NOI2018]$归程 $kruscal$重构树
正解:$kruscal$重构树 解题报告: 传送门$QwQ$ 语文不好选手没有人权$TT$连题目都看不懂真的要哭了$kk$ 所以先放个题目大意?就说给定一个$n$个点,$m$条边的图,每条边有长度和海 ...
- NOI2018Day1T1 归程 并查集 kruskal kruskal重构树 倍增表 Dijkstra
原文链接https://www.cnblogs.com/zhouzhendong/p/NOI2018Day1T1.html 题目传送门 - 洛谷P4768 题意 给定一个无向连通图,有 $n$ 个点 ...
- NOI Day1T1归程(Kruskal重构树+Dijkstra)
NOI Day1T1归程(Kruskal重构树+Dijkstra) 题目 洛谷题目传送门 题解 其实我不想写......,所以...... 挖个坑......我以后一定会补的 luogu的题解讲的还是 ...
随机推荐
- ShadowMap渲染阴影方法及问题 【转】
ShadowMap基于的原理:SM算法是一个2-pass绘制算法,第一pass从光源视点绘制场景,生成SM纹理,第2pass从视点视图按常规方法绘制场景 从光源的位置观察场景,这时候我们看不到的地方就 ...
- 转: How to Install MongoDB 3.2 on CentOS/RHEL & Fedora (简单易懂)
from: http://tecadmin.net/install-mongodb-on-centos-rhel-and-fedora/ MongoDB (named from “huMONGOus ...
- Android记录24-WebView实现白天/夜间阅读模式
前言 本篇博客给大家分享一个WebView的使用案例.实现Android调用JavaScript代码来控制白天/夜间模式. 关于WebView怎样使用,官网有非常好的说明,Building Web A ...
- Nginx优化指南+LINUX内核优化+linux连接数优化+nginx连接数优化
Most setup guides for Nginx tell you the basics - apt-get a package, modify a few lines here and the ...
- Python生成8位随机字符串的一些方法
#第一种方法 import random import string seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP ...
- Vb.net/VB 声明API函数实现父窗口功能
回想第一次敲机房收费.自己调用了api函数实现了父窗口及其子窗口最小化的功能.现在再次遇到,自己就在思考,能不能继续使用API函数呢?答案当然是Of Course! 事实上细致看两者并没有多大的差别. ...
- 【C语言】求两个数中不同的位的个数
//求两个数中不同的位的个数 #include <stdio.h> int count_different(int a, int b) { int count = 0; int c = a ...
- JS 模板引擎 Handlebars.js 中文说明
Handlebars 为你提供了一个可以毫无挫折感的高效率书写 语义化的模板 所必需的一切. Mustache 模板和 Handlebars 是兼容的,所以你可以把Mustache模板拿来导入到Han ...
- C++中字符数组和字符串string
字符数组 C++中字符数组用char str[]能够用来表示一个字符串. (1) 数组的大小和字符串的长度. 数组的大小一定要大于字符串的长度,由于系统会自己主动补上一个'\0'作为字符串的结束标 ...
- HashSet、LinkHashSet、TreeSet总结
HashSet:散列集,集合中的元素不允许重复,但是不要求顺序,输出的顺序和进入HashSet的顺序是没有关系的 LinkedHashSet :链表散列集,集合中的元素不允许重复,同时要求和进入Set ...