题目:

在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

题解:

这道题貌似是Kruskal重构树的板子题.
很长时间以前做了加强版,现在才发现还有未加强版.

赶紧把代码粘了过来水了过去.
(还记得写这份代码的时候被卡内存,用了po姐的主席树模板才过去的)

#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){x=0;char ch;bool flag = false;while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 200200;
const int inf = 0x3f3f3f3f;
struct Edge{int to,next;
}G[maxn];
int head[maxn],cnt;
void add(int u,int v){G[++cnt].to = v;G[cnt].next = head[u];head[u] = cnt;
}
struct edge{int u,v,d;bool friend operator < (const edge &a,const edge &b){return a.d < b.d;}
}zs[500500];
int n,w[maxn],ufa[maxn],m,q;
int fa[maxn][20],dis[maxn][20];
int find(int u){return ufa[u] == u ? u : ufa[u] = find(ufa[u]);
}
void Kruskal(){sort(zs+1,zs+m+1);int nc = 0;for(int i=1;i<=m;++i){int x = find(zs[i].u);int y = find(zs[i].v);if(x != y){ufa[x] = ufa[y] = ++n;ufa[n] = n;fa[x][0] = n;fa[y][0] = n;dis[x][0] = dis[y][0] = zs[i].d;add(n,x);add(n,y);if(++nc == n-1) break;}}
}
int dfn[maxn],ind[maxn],oud[maxn];
int dfs_clock;
#define v G[i].to
void dfs(int u){ind[u] = ++dfs_clock;dfn[ind[u]] = w[u];for(int i = head[u];i;i=G[i].next){dfs(v);}oud[u] = dfs_clock;
}
#undef v
struct Node{Node *ls,*rs;int num;void* operator new (size_t size,Node *_,Node *__,int ___);
}*tree[maxn],*mempool,*C,*null;
void* Node :: operator new (size_t size,Node *_,Node *__,int ___){if(C==mempool){C=new Node[1<<15];mempool=C+(1<<15);}C->ls=_;C->rs=__;C->num=___;return C++;
}
Node* build(Node *p,int x,int y,int val){int mid=x+y>>1;if(x==y) return new (null,null,p->num+1) Node;if(val<=mid) return new (build(p->ls,x,mid,val),p->rs,p->num+1) Node;else return new (p->ls,build(p->rs,mid+1,y,val),p->num+1) Node;
}
int Kth(Node *p1,Node *p2,int x,int y,int k){int l = x,r = y;while(l != r){int x = p2->rs->num-p1->rs->num;int mid = l+r >> 1;if(k <= x){p1 = p1->rs;p2 = p2->rs;l = mid+1;}else{p1 = p1->ls;p2 = p2->ls;r = mid;k -= x;}}return l;
}
int get_rt(int x,int y){for(int j=19;~j;--j){if(fa[x][j] && dis[x][j] <= y){x = fa[x][j];}}return x;
}
int main(){read(n);read(m);read(q);for(int i=1;i<=n;++i){read(w[i]);ufa[i] = i;}for(int i=1;i<=m;++i){read(zs[i].u);read(zs[i].v);read(zs[i].d);}Kruskal();for(int j = 1;j<= 19;++j){for(int i=1;i<=n;++i){fa[i][j] = fa[fa[i][j-1]][j-1];dis[i][j] = cat_max(dis[i][j-1],dis[fa[i][j-1]][j-1]);}}dfs(n);null=new (0x0,0x0,0) Node;null->ls=null->rs=null;tree[0] = null;for(int i=1;i<=n;++i){tree[i] = build(tree[i-1],0,1000000000,dfn[i]);}int u,v,k,ans = 0;while(q--){read(u);read(v);read(k);int x = get_rt(u,v);if(oud[x] - ind[x] + 1 < k){puts("-1");ans = 0;continue;}ans = Kth(tree[ind[x]-1],tree[oud[x]],0,1000000000,k);if(ans == 0){puts("-1");continue;}printf("%d\n",ans);}getchar();getchar();return 0;
}

转载于:https://www.cnblogs.com/Skyminer/p/6592612.html

bzoj 3545: [ONTAK2010]Peaks Kruskal重构树相关推荐

  1. 洛谷 - P4197 Peaks(Kruskal重构树+dfs序+主席树)

    题目链接:点击查看 题目大意:有 n 座山峰,每座山峰有他的高度 h[ i ] ,有些山峰之间有双向道路相连,共 m 条路径,每条路径有一个困难值,这个值越大表示越难走. 现在有 q 组询问,每组询问 ...

  2. BZOJ.4144.[AMPPZ2014]Petrol(Kruskal重构树)

    BZOJ 看别人代码的时候发现哪一步都很眼熟,突然想起来,就在四个月前我好像看过还给别人讲过?mmp=v= 果然不写写就是容易忘.写了好歹忘了的时候还能复习呢(虽然和看别人的好像也没多少差别?). 首 ...

  3. [ONTAK2010] Peaks加强版 (kruskal重构树+主席树+倍增)

    Peaks description solution code description 在Bytemountains有N座山峰,每座山峰有他的高度h_i 有些山峰之间有双向道路相连,共M条路径,每条路 ...

  4. kruskal 重构树(讲解 + 例题)

    kruskal重构树 如何建树 模仿kruskalkruskalkruskal,先将所有边排序. 依次遍历每一条边,如果这条边的两个节点(u,vu, vu,v)不在同一个连通块里面, 则新建一个nod ...

  5. LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)

    LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...

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

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

  7. Kruskal 重构树

    Kruskal 重构树 kruskal 最小生成树算法相信大家已经很熟悉了,所以这里就不介绍了.顾名思义 kruskal 重构树就是根据 kruskal 改造一下衍生出来的算法.它能解决下面这样的一个 ...

  8. kruskal重构树练习

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

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

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

  10. 【NOI 2018】归程(Kruskal重构树)

    题面在这里就不放了. 同步赛在做这个题的时候,心里有点纠结,很容易想到离线的做法,将边和询问一起按水位线排序,模拟水位下降,维护当前的各个联通块中距离$1$最近的距离,每次遇到询问时输出所在联通块的信 ...

最新文章

  1. Windows Phone Developer Tools Beta 发布
  2. STL(八)——向量vector
  3. NLP领域,哪些综述性的文章值得推荐?
  4. 如何使用SQL Server游标
  5. 重新想象 Windows 8 Store Apps (35) - 通知: Toast 详解
  6. 《数字孪生体技术白皮书》重磅发布(附完整版下载)
  7. 软件开发项目计划书编写说明
  8. 津巴布韦 apn_津巴布韦的回忆-你负担不起回家
  9. 阿里月饼事件被辞程序员冤吗
  10. mysql链接is not allow_解决Mysql远程连接出错不允许访问 ERROR 1130:Host is not allow...
  11. MATLAB--数字图像处理 图像平移
  12. 看看最新的考试 c语言 noip模拟 纯llq原创作品
  13. Krpano vtourskin.xml 默认皮肤详解
  14. 《数据结构教程》(第5版)学习笔记(一)
  15. 【原创】2019.10.24模拟赛 嘟嘟噜/天才绅士少女助手克里斯蒂娜/凤凰院凶真
  16. php狼找兔子问题算法,算法 狼找兔子问题
  17. 交通运输——机器学习/深度学习资源列表
  18. js判断两个字符串相等问题
  19. 谈谈市面上无线路由器的性能和芯片
  20. Mask R-CNN完整翻译

热门文章

  1. 用R和BioConductor进行基因芯片数据分析(三):计算median
  2. Silverlight 2.0的了解
  3. nyoj 19 擅长排列的小明(深搜,next_permutation)
  4. getContentResolver()内容解析者查询联系人、插入联系人
  5. sharepoint 2013 配件控制FileUpload如何检查是否图像的方法
  6. [转]AndroidManifest.xml文件详解
  7. 杭电ACM求平均成绩
  8. [iOS]学习笔记3(动态性)
  9. shell的函数返回值
  10. JAVA程序打包成exe文件详细图解