题目链接:点击查看

题目大意:去原网址看吧

题目分析:因为是在刷克鲁斯卡尔重构树的题目,所以稍微思考一下就能想出解法了,首先如果水位线固定了,剩下的边组成的最小生成树也是一定的,此时同一个连通块内的点对答案的贡献都是相同的,因为车子可以随便开,这样连通块的贡献,就是连通块内距离点 1 最近的点了

这样如何找相应的连通块呢?可以对所有边降序排序,建立克鲁斯卡尔重构树,对于点 x 来说,找到权值大于水位线,且深度最小的祖先,这一步可以用树上倍增来完成,此时这个祖先的子树中的点两两都可以互相达到了,显然包括了点 x ,只需要求出这些点中距离点 1 最近的点就好了

至于如何求出某个点的子树中,距离点 1 最近的点,这个预先跑一下迪杰斯特拉,在重构树建好后,在树上跑一边 dfs 就好了

相对于上一道题目来说比较简单,好多代码直接复用下来的(懒):https://blog.csdn.net/qq_45458915/article/details/108187207

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=4e5+100;const int M=8e5+100;template<typename T>
struct Dij
{const static int N=4e5+100;const static int M=8e5+100;struct Edge{int to,next;T w;}edge[M];int head[N],cnt;//链式前向星 T d[N];bool vis[N];void addedge(int u,int v,T w){edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;}struct Node{int to;T w;Node(int TO,T W){to=TO;w=W;}bool operator<(const Node& a)const{return w>a.w;}};void Dijkstra(int st){priority_queue<Node>q;memset(vis,false,sizeof(vis));memset(d,0x3f,sizeof(d));d[st]=0;q.push(Node(st,0));while(q.size()){Node cur=q.top();int u=cur.to;q.pop();if(vis[u])continue;vis[u]=true;for(int i=head[u];i!=-1;i=edge[i].next)//扫描出所有边 {int v=edge[i].to;T w=edge[i].w;if(d[v]>d[u]+w)//更新 {d[v]=d[u]+w;q.push(Node(v,d[v]));}}}}void init(){memset(head,-1,sizeof(head));cnt=0; }
};Dij<int>dij;int n,m,limit,dp[N][25],f[N],ans[N],val[N];struct Edge
{int u,v,w,h;bool operator<(const Edge& t)const{return h>t.h;}
}edge[N];vector<int>node[N];void dfs(int u,int fa)
{ans[u]=dij.d[u];dp[u][0]=fa;for(int i=1;i<=limit;i++)dp[u][i]=dp[dp[u][i-1]][i-1];for(auto v:node[u]){if(v==fa)continue;dfs(v,u);ans[u]=min(ans[u],ans[v]);}
}
/*并查集+克鲁斯卡尔重构树*/
int find(int x)
{return f[x]==x?x:f[x]=find(f[x]);
}void Ex_Kruskal()
{int index=n;for(int i=1;i<=n<<1;i++)f[i]=i;sort(edge+1,edge+1+m);for(int i=1;i<=m;i++){int xx=find(edge[i].u),yy=find(edge[i].v);if(xx!=yy){f[xx]=f[yy]=++index;val[index]=edge[i].h;node[index].push_back(xx);node[index].push_back(yy);}}
}
/*并查集+克鲁斯卡尔重构树*/
int get_pos(int u,int up)//树上倍增找满足的祖先
{for(int i=20;i>=0;i--)if(dp[u][i]!=0&&val[dp[u][i]]>up)u=dp[u][i];return u;
}void init(int n)
{for(int i=1;i<=n<<1;i++)node[i].clear();limit=log2(n)+1;dij.init();
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){scanf("%d%d",&n,&m);init(n);for(int i=1;i<=m;i++){scanf("%d%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w,&edge[i].h);dij.addedge(edge[i].u,edge[i].v,edge[i].w);dij.addedge(edge[i].v,edge[i].u,edge[i].w);}dij.Dijkstra(1);Ex_Kruskal();dfs(find(1),0);int q,k,s,last=0;scanf("%d%d%d",&q,&k,&s);while(q--){int v,p;scanf("%d%d",&v,&p);v=(v+k*last-1)%n+1;p=(p+k*last)%(s+1);v=get_pos(v,p);printf("%d\n",last=ans[v]);}}return 0;
}

洛谷 - P4768 [NOI2018]归程(Kruskal重构树+树上倍增+最短路)相关推荐

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

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

  2. P4768 [NOI2018] 归程 Kruskal重构树 + 倍增 + 最短路

    传送门 文章目录 题意: 思路: 题意: 给你一个联通无向图,每条边有一个长度lll和海拔aaa,当海拔≤\le≤水位线的时候,说明这个道有积水.在起始点有一辆车,车可以走没有积水的路,下车后可以走有 ...

  3. LOJ.2718.[NOI2018]归程(Kruskal重构树 倍增)

    LOJ2718 BZOJ5415 洛谷P4768 Rank3+Rank1无压力 BZOJ最初还不是一道权限题... Update 2019.1.5 UOJ上被hack了....好像是纯一条链的数据过不 ...

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

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

  5. 洛谷P2245 星际导航(kruskal重构树)

    sideman 做好了回到 \text{Gliese}Gliese 星球的硬件准备,但是 \text{sideman}sideman 的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有 ...

  6. [NOI2018] 归程(线段树维护并查集的可持久化/kruskal重构树,倍增+dijkstra最短路)

    [NOI2018] 归程 description solution1 code1 solution2 code description 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要 ...

  7. NOI 2018 归程 (Kruskal重构树)

    题目大意:太长了,略 Kruskal重构树,很神奇的一个算法吧 如果两个并查集被某种条件合并,那么这个条件作为一个新的节点连接两个并查集 那么在接下来的提问中,如果某个点合法,它的所有子节点也都合法, ...

  8. 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值

    传送门 其实NOIP某些年的第三题也并不是很难嘛... 题目分析: 题目中要求求出某两点之间可以运输的最大重量,也就是这两个点的某条路径上边权最小的边的权值的最大值 很显然,题目中的运输最大重量与选择 ...

  9. kruskal重构树练习

    洛谷 P4197 Peaks 题意: 有 nnn 个山峰,每一个山峰高 hih_ihi​ ,有 mmm 条双向带权边将一些山峰连接起来,有 qqq 次询问,每次询问 (v,x,k)(v,x,k)(v, ...

最新文章

  1. 高并发场景下数据库的常见问题及解决方案
  2. HTML5基础-Mark标签高亮显示文本
  3. Julia程序设计2 数值类型
  4. 国内外交互体验很好的十款验证码
  5. first-child和first-of-type的区别
  6. 与计算机技术发展密切相关的科学家,关于计算机科学与技术的发展趋势探究
  7. StarkWare推出ZK Rollup扩容解决方案StarkNet
  8. C语言中用二进制输出一个数字
  9. 网络技术——网络安全技术
  10. java代码禁止反编译_Java代码防止反编译
  11. 计算机无法打开文档,电脑txt文件打不开怎么办-修复电脑中无法打开txt文档的方法 - 河东软件园...
  12. python简单文件服务器
  13. 《黑客帝国》代码雨——源代码
  14. 【柒】企业分析利器——强大企业模型
  15. 苹果iphone5/iphone5s充电器(A1443)及电路原理图
  16. mysql where 小于_MySQL-过滤数据(WHERE语句)
  17. java程序员月薪3万需要掌握哪些技术?技术水平需要到什么程度?
  18. 12306html布局,12306-Assistant
  19. 深圳市工业和信息化局关于征集创新产品的通知
  20. 基于Epoll的Reactor模式

热门文章

  1. linux blind函数,Linux网络编程入门
  2. erp系统方案书_解决方案 |快普M8为系统集成企业定制的ERP系统
  3. Redis AOF带来的问题
  4. MySQL服务端的登录和退出
  5. MySQL 高级 - 触发器 - 创建及应用
  6. 任务执行者EventLoop
  7. 高仿真的类-ApplicationContextAware
  8. 用户user空间和内核kernel空间
  9. 依赖注入_List_Set_Array类型的注入
  10. 使用ln -s解决库冲突的问题