题目描述

给定一个 n 个点 m 条边的无向连通图,编号为 1 到 n ,没有自环,可能有重边,每一条边有一个正权值 w 。
给出 q 个询问,每次给出两个不同的点 u 和 v ,求一条从 u 到 v 的路径上边权的最大值最小是多少。

输入格式

输入第一行两个整数 n, m。

接下来 m 行,每行三个整数 ai, bi, wi (ai != bi),表示一条边 (ai​, bi​),边权为 wi​。

接下来一行一个整数 q,表示询问数量。

接下来一行四个整数 A,B,C,P,表示询问的生成方式。

由于本题数据规模较大,直接输入输出会占用比计算多数倍的时间,因此对询问的输入输出进行了压缩。

输入压缩方法是:读入4个整数 A,B,C,P,每次询问调用以下函数生成 u 和 v:

int A,B,C,P;
inline int rnd(){return A=(A*B+C)%P;}

每次询问时的调用方法为:

u=rnd()%n+1,v=rnd()%n+1;

若u和v相等则答案为0。

数据保证 0<=A<P,0<=C<P,P(B+1)<2^31-1

输出格式

输出共一行一个整数,表示所有询问的答案之和模 1000000007 的值。

由于本题数据规模较大,直接输入输出会占用比计算多数倍的时间,因此对询问的输入输出进行了压缩。

输出压缩方法是:输出所有询问的答案之和模 1000000007 的值。

样例

输入

5 7
1 2 8
2 3 9
3 1 2
3 4 7
1 4 4
3 5 6
1 4 9
10
233 17 66666 19260817

输出

32

数据范围与提示

思路

首先可以证明,两点之间边权最大值最小的路径一定是在最小生成树上。考虑到这题是边权的最大值,直接把重构树建出来,然后查LCA处的权值即可。由于输入文件过大,需要用RMQ算法求LCA。

AC_Code

#include <bits/stdc++.h>
const int MAXN=1e6+10, mod=1e9+7;
using namespace std;inline int read() {char c=getchar();int x=0, f=1;while (c<'0' || c>'9') {if(c=='-')    f=-1;c=getchar();}while (c>='0' && c<='9')  x=x*10+c-'0', c=getchar();return x*f;
}int N,M,fa[MAXN],tot,val[MAXN],id[MAXN][21],num,dfn[MAXN],dep[MAXN],lg2[MAXN];struct Edge {int u, v, w;bool operator<(const Edge &rhs) const { return w < rhs.w; }
} E[MAXN];vector<int> v[MAXN];int find(int x) {return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}void Kruskal()
{for (int i=1; i<=2*N; i++)  fa[i]=i;tot = N;for(int i=1; i<=M; i++) {int x = find(E[i].u), y = find(E[i].v);if(x==y)    continue;val[++tot] = E[i].w;v[tot].push_back(x);v[tot].push_back(y);v[x].push_back(tot);v[y].push_back(tot);fa[x] = tot;fa[y] = tot;}
}void dfs(int x, int fa)
{dfn[x] = ++num;dep[x] = dep[fa]+1;id[num][0] = x;for (int i=0, to; i<v[x].size(); i++) {if((to=v[x][i])==fa)    continue;dfs(to, x);id[++num][0] = x;}
}void RMQ() {for(int i=2; i<=num; i++)  lg2[i] = lg2[i>>1] + 1;for(int j=1; j<=20; j++)for(int i=1; i+(1<<j)-1<=num; i++) {int r = i+(1<<(j-1));id[i][j] = (dep[id[i][j-1]] < dep[id[r][j-1]]) ? id[i][j-1] : id[r][j-1];}
}int A, B, C, P;
inline int rnd() { return A = (A*B+C) % P; }int LCA(int x, int y) {x = dfn[x];y = dfn[y];if (x > y)swap(x, y);int k = lg2[y - x + 1];return dep[id[x][k]] < dep[id[y - (1 << k) + 1][k]] ? id[x][k] : id[y - (1 << k) + 1][k];
}int main() {N = read();M = read();for (int i = 1; i <= M; i++) {int x = read(), y = read(), z = read();E[i] = (Edge){ x, y, z };}sort(E + 1, E + M + 1);Kruskal();dfs(tot, 0);RMQ();int ans = 0, Q = read();A = read();    B = read();C = read();    P = read();while (Q--) {int u = rnd() % N + 1, v = rnd() % N + 1;(ans += val[LCA(u, v)]) %= mod;}printf("%d", ans);return 0;
}

【数据结构】最小瓶颈路 加强版(Kruskal重构树RMQ求LCA)相关推荐

  1. bzoj3551 [ONTAK2010]Peaks加强版 kruskal重构树

    最大边最小,就是最小生成树,可以考虑用主席树维护father数组,但不能遍历子集查找 然后就只能牺牲一部分空间时间来多存一些东西 多存的就是边值大小顺序,本来以为是用主席树排边值,结果由于此题有2种数 ...

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

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

  3. Kruskal重构树

    构建方法 把生成树的每个边拆成一个点表示,点权即为原来的边权,添加两个边指向原来的点.这样kruskalkruskalkruskal重构树就有2∗n−12*n-12∗n−1个点 性质 叶子节点对应之前 ...

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

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

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

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

  6. Kruskal重构树 学习笔记

    Kruskal重构树 学习笔记 文章目录 Kruskal重构树 学习笔记 前言 例题1 BZOJ3732 Network 例题2 [NOI2018] 归程 前言 Kruskal重构树是一种比较冷门的算 ...

  7. P1967 货车运输( 最大生成树+LCA or Kruskal重构树)

    至于为什么要用最大生成树!? 理由:因为问最大载重,如果要加大载重的话,对于选择的路肯定权重越大越好,所以贪心地想,得用到最大生成树.然后两点之间的最大载重用LCA去寻找就可以了. 最大生成树+LCA ...

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

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

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

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

最新文章

  1. 电脑温度检测软件哪个好_一般电脑录音软件哪个好?
  2. -16 | 12 等于多少
  3. python进程监控并重启
  4. 平衡二叉树平衡因子_数据结构:平衡二叉树
  5. .NET EFCore之增删改查
  6. Java黑皮书课后题第6章:*6.21(电话按键盘)国际标准的字母/数字匹配图如编程练习题4.15所示。编写一个测试程序,提示用户输入字符串形式的电话号码。程序将字母(大写或小写)翻译成数字
  7. HTML5 CSS3初学者指南(3) – HTML5新特性
  8. 围成一圈的排列组合问题_分班必考知识点!小学奥数之排列组合问题
  9. vue --- 子组件监听点击事件,接收父组件参数.实现对应跳转
  10. NOIP模拟测试29「爬山·学数数·七十和十七」
  11. 解决:-source 1.6 中不支持 diamond 运算符 [ERROR] (请使用 -source 7 或更高版本以启用 diamond 运算符)
  12. 兵乓球- 经典街机游戏-python小游戏源码下载
  13. Spring使用Cache、整合Ehcache
  14. easyui获取图片路径_094 ego电商项目-2 菜单、图片上传、CRUD
  15. KMP模式匹配算法——C++
  16. 免费的录屏软件Capture
  17. 上三角、下三角、对称矩阵
  18. 通过图书编号查询python_基于Python的图书ISBN查询接口调用代码实例
  19. Vue+element+Nodejs学习记录(6)
  20. PC/UVa 题号: 110106/10033 Interpreter (解释器)题解 c语言版

热门文章

  1. C++初学者必练基础编程题【第一期】
  2. 爬虫-东北林业大学校内-中国[哈尔滨]森林博物馆-爬取所有馆藏蝴蝶图片
  3. vue-cli3打包时图片压缩处理
  4. 关于0x80070091 目录不是空的
  5. Mac下eclipse安装和配置Tomcat
  6. Android NFC基础
  7. java mysql连接池配置_Java数据库连接池的几种配置方法(以MySQL数据库为例)
  8. IntelliJ IDEA中怎么查看方法说明
  9. 奶酪巫师的黑客乐园 - 第一个进行硬分叉的区块链游戏?
  10. 行走在思想的边上――武墩支教十二月(上)