【NOI2018】归程(克鲁斯卡尔重构树)

题面

洛谷

题解

我在现场竟然没有把这道傻逼题给切掉,身败名裂。

因为这题就是克鲁斯卡尔重构树的模板题啊

我就直接简单的说一下把

首先发现答案就是在只经过海拔大于\(p\)的边的情况下,所有点到\(1\)号点中最短路最小的那个点。所以预处理最短路径,构建克鲁斯卡尔重构树,直接倍增+线段树就好了。

还有一种基于离线做法的方法。

我们发现离线做法只需要按照所有询问排序,

然后利用并查集按照海拔高度从小往大合并(这个其实就是克鲁斯卡尔)

这样子就可以利用可持久并查集解决。

发现并不需要回朔时间并修改,而只需要查询历史版本的值。

因为每次增加一条边只会修改两个集合,所以可以使用一个\(vector\)存下每个点每次修改之后的父亲以及当前修改的时间,那么每次询问的时候只需要在对应的点上二分查询在目标时间的集合父亲就好了,合并使用启发式合并,保证复杂度是\(O(nlogn+Qlogn)\)。

我的代码是克鲁斯卡尔重构树

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
#define MAX 200200
#define pir pair<int,int>
#define mpi make_pair
#define fr(x) (x.first)
#define sd(x) (x.second)
#define lson (now<<1)
#define rson (now<<1|1)
inline int read()
{
int x=0;bool fl=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')fl=true,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
return fl?-x:x;
}
struct Edge{int u,v,w,s;}E[MAX<<1];
bool operator<(Edge a,Edge b){return a.s>b.s;}
struct Line{int v,next,w,s;}e[MAX<<2];
int h[MAX<<1],cnt=1;
inline void Add(int u,int v,int w,int s){e[cnt]=(Line){v,h[u],w,s};h[u]=cnt++;}
int n,m,dis[MAX],Q,typ,S;
bool vis[MAX];
namespace SP
{
priority_queue<pir,vector<pir>,greater<pir> >Q;
void Dijkstra()
{
memset(vis,0,sizeof(vis));
while(!Q.empty())Q.pop();
Q.push(mpi(0,1));
while(!Q.empty())
{
pir u=Q.top();Q.pop();
if(vis[sd(u)])continue;vis[sd(u)]=true;
dis[sd(u)]=fr(u);
for(int i=h[sd(u)];i;i=e[i].next)
if(!vis[e[i].v])Q.push(mpi(dis[sd(u)]+e[i].w,e[i].v));
}
}
}
namespace MST
{
int f[MAX<<1],id;
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
void init(){for(int i=1;i<=n<<1;++i)f[i]=i;id=n;}
void Kursual()
{
init();
for(int i=1;i<=m;++i)
{
int u=getf(E[i].u),v=getf(E[i].v);
if(u==v)continue;++id;
Add(id,u,E[i].w,E[i].s);Add(id,v,E[i].w,E[i].s);
f[u]=f[v]=id;
}
}
}
int dfn[MAX<<1],low[MAX<<1],tim,ln[MAX<<1];
int p[20][MAX<<1],s[20][MAX<<1];
void dfs(int u)
{
if(u<=n)dfn[u]=++tim,ln[tim]=u;else dfn[u]=1e9;
for(int i=1;i<20;++i)p[i][u]=p[i-1][p[i-1][u]];
for(int i=1;i<20;++i)s[i][u]=min(s[i-1][u],s[i-1][p[i-1][u]]);
for(int i=h[u];i;i=e[i].next)
{
p[0][e[i].v]=u;s[0][e[i].v]=e[i].s;
dfs(e[i].v);dfn[u]=min(dfn[u],dfn[e[i].v]);
}
low[u]=tim;
}
void init(){memset(h,0,sizeof(h));cnt=1;tim=0;}
int t[MAX<<2];
void Build(int now,int l,int r)
{
if(l==r){t[now]=dis[ln[l]];return;}
int mid=(l+r)>>1;
Build(lson,l,mid);Build(rson,mid+1,r);
t[now]=min(t[lson],t[rson]);
}
int Query(int now,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return t[now];
int mid=(l+r)>>1,ret=2147483647;
if(L<=mid)ret=min(ret,Query(lson,l,mid,L,R));
if(R>mid)ret=min(ret,Query(rson,mid+1,r,L,R));
return ret;
}
int Jump(int u,int r)
{
for(int i=19;~i;--i)
if(p[i][u]&&s[i][u]>r)u=p[i][u];
return u;
}
int main()
{
freopen("return.in","r",stdin);
freopen("return.out","w",stdout);
int T=read();
while(T--)
{
init();n=read();m=read();
for(int i=1;i<=m;++i)
{
int u=read(),v=read(),l=read(),s=read();
E[i]=(Edge){u,v,l,s};
Add(E[i].u,E[i].v,E[i].w,E[i].s);
Add(E[i].v,E[i].u,E[i].w,E[i].s);
}
sort(&E[1],&E[m+1]);
SP::Dijkstra();init();
memset(p,0,sizeof(p));memset(s,0,sizeof(s));
MST::Kursual();dfs(MST::id);
Build(1,1,n);
Q=read();typ=read();S=read();
int lans=0,v,p;
while(Q--)
{
v=(read()+typ*lans-1)%n+1;
p=(read()+typ*lans)%(S+1);
v=Jump(v,p);
printf("%d\n",lans=Query(1,1,n,dfn[v],low[v]));
}
}
return 0;
}

【BZOJ5415】【NOI2018】归程(克鲁斯卡尔重构树)的更多相关文章

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

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

  2. [note]克鲁斯卡尔重构树

    克鲁斯卡尔重构树 又叫并查集重构树 大概在NOI2018之前还是黑科技 现在?烂大街了 主要是针对图上的对边有限制的一类问题 比如每次询问一个点u不能经过边权大于w的边能走到的第k大点权是多少 也就是 ...

  3. [您有新的未分配科技点][BZOJ3545&BZOJ3551]克鲁斯卡尔重构树

    这次我们来搞一个很新奇的知识点:克鲁斯卡尔重构树.它也是一种图,是克鲁斯卡尔算法求最小生成树的升级版首先看下面一个问题:BZOJ3545 Peaks. 在Bytemountains有N座山峰,每座山峰 ...

  4. 洛谷P4197 Peaks&&克鲁斯卡尔重构树学习笔记(克鲁斯卡尔重构树+主席树)

    传送门 据说离线做法是主席树上树+启发式合并(然而我并不会) 据说bzoj上有强制在线版本只能用克鲁斯卡尔重构树,那就好好讲一下好了 这里先感谢LadyLex大佬的博客->这里 克鲁斯卡尔重构树 ...

  5. 【BZOJ4242】水壶(克鲁斯卡尔重构树,BFS)

    [BZOJ4242]水壶(克鲁斯卡尔重构树,BFS) 题面 BZOJ然而是权限题. Description JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长 ...

  6. 洛谷 P1967 货车运输(克鲁斯卡尔重构树)

    题目描述 AAA国有nn n座城市,编号从 11 1到n nn,城市之间有 mmm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qqq 辆货车在运输货物, 司机们想知道每辆车在不超过车 ...

  7. [模板] Kruskal算法 && 克鲁斯卡尔重构树

    克鲁斯卡尔重构树 发现没把板子放上来... 现在放一下 克鲁斯卡尔算法的正确性是利用反证法证明的. 简要地说, 就是如果不加入当前权值最小的边 \(e_1\), 那么之后加入的边和这条边会形成一个环. ...

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

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

  9. P4197 Peaks [克鲁斯卡尔重构树 + 主席树][克鲁斯卡尔重构树学习笔记]

    Problem 在\(Bytemountains\)有\(n\)座山峰,每座山峰有他的高度\(h_i\) .有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个困难值,这个值越大表示越难走, ...

随机推荐

  1. logstash处理@timestamp时区

    input { stdin { } } filter { #ruby { # code => "event.set('timestamp', event.get('@timestamp ...

  2. JavaWeb(十三)——使用Session防止表单重复提交

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提 ...

  3. 「Leetcode」975. Odd Even Jump(Java)

    分析 注意到跳跃的方向是一致的,所以我们需要维护一个数接下来跳到哪里去的问题.换句话说,就是对于一个数\(A_i\),比它大的最小值\(A_j\)是谁?或者反过来. 这里有两种方案,一种是单调栈,简单 ...

  4. MySQL高性能优化实战总结

    1.1 前言 MySQL对于很多Linux从业者而言,是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多 ...

  5. Echarts-K线图提示框改头换面

    工作: 使用Hbuilder建web工程,加入echarts相关库,根据需要更改K线图及其的提示样式,去除默认提示,使用异步加载echarts的数据,数据格式为json. 需要注意的K线图和5日均线, ...

  6. leetcode个人题解——#39 Combination Sum

    思路:先对数据进行排序(看评论给的测试数据好像都是有序数组了,但题目里没有给出这个条件),然后回溯加剪枝即可. class Solution { public: ; vector<vector& ...

  7. 0512 SCRUM团队项目3.0

    题目 SCRUM 流程的步骤2: Spring 计划 1. 确保product backlog井然有序.(参考示例图1) 2. Sprint周期,一个冲刺周期,长度定为两周,本学期还有三个冲刺周期. ...

  8. lintcode-418-整数转罗马数字

    418-整数转罗马数字 给定一个整数,将其转换成罗马数字. 返回的结果要求在1-3999的范围内. 说明 什么是 罗马数字? https://en.wikipedia.org/wiki/Roman_n ...

  9. IO流详解

    目录 IO流 IO流概述及其分类 IO概念 流按流向分为两种: 流按操作类型分为两种: 常用的IO流类 字节流的抽象父类: 字符流的抽象父类: InputStream & FileInputS ...

  10. 201621123037 《Java程序设计》第10周学习总结

    作业10-异常 标签(空格分隔): Java 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7 ...