[JZOJ4899] 雪之国度
题目描述
雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路。雪之女王赋予了每一座城市不同的能量,其中第i座城市被赋予的能量为Wi。
如果城市u和v之间有一条道路,那么只要此刻雪之女王的能量不小于|Wu-Wv|,这条道路就是安全的。如果城市u和v之间存在两条没有重复道路的安全路径(其中每一段道路都是安全的),则认为这两座城市之间有着良好的贸易关系。
最近,雪之女王因为情感问题,她的能量产生巨大的波动。为了维持雪之国度的经济贸易,她希望你能帮忙对Q对城市进行调查。对于第j对城市uj和vj,她希望知道在保证这两座城市之间有着良好贸易关系的前提之下,自己最少需要保持多少的能量。
数据范围
对于 $20\%$ 的数据,$3 \leq N \leq 10$,$3 \leq M \leq 20$,$1 \leq Q \leq 10$
对于另 $30\%$ 的数据,$W=0$
对于 $100\%$ 的数据,$3 \leq N \leq 10^5$,$3 \leq M \leq 5 \times 10^5$,$1 \leq Q \leq 10^5$
分析
这题大意就是问至少经过权值为多少的边,使得两点之间存在两条不经过重复边的路径(边双)
首先可以建一棵最小生成树,这样每两个点之间有且仅有一条路径,而且权值最大的边一定是在另一条路径(非树边)上
然后从小到大依次加入非树边,每次加入边一定会形成一个环,由于最小生成树上的边权对答案是无意义的,所以我们可以直接把环上所有没更新过的树边的权值更新为该非树边的权值
但是如果每次都把环上的所有路径走一遍,就很容易超时,所以需要用并查集维护已经更新过的点,这样就不会对一条边重复访问了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100005
#define M 500005
#define T 17 int n, m, q, tot = , cnt;
int to[M << ], nxt[M << ], head[N];
int fa[N], val[N], used[M], d[N];
int f[N][], g[N][]; struct Edge {
int u, v, w;
} e[M]; bool cmp(Edge a, Edge b) {
return a.w < b.w;
} void add(int u, int v) {
to[++tot] = v; nxt[tot] = head[u]; head[u] = tot;
} int find(int x) {
if (x == fa[x]) return x;
return fa[x] = find(fa[x]);
} void dfs(int x, int ff) {
d[x] = d[ff] + ; f[x][] = ff;
for (int i = ; ( << i) < d[x]; i++)
f[x][i] = f[f[x][i - ]][i - ];
for (int i = head[x]; i; i = nxt[i])
if (to[i] != ff) dfs(to[i], x);
} int lca(int x, int y) {
int ans = ;
if (d[x] < d[y]) swap(x, y);
for (int i = T; i >= ; i--)
if (d[f[x][i]] >= d[y])
ans = max(ans, g[x][i]), x = f[x][i];
if (x == y) return ans;
for (int i = T; i >= ; i--)
if (f[x][i] != f[y][i]) {
ans = max(ans, max(g[x][i], g[y][i]));
x = f[x][i]; y = f[y][i];
}
ans = max(ans, max(g[x][], g[y][]));
return ans;
} int main() {
scanf("%d%d%d", &n, &m, &q);
for (int i = ; i <= n; i++)
scanf("%d", val + i);
for (int i = ; i <= m; i++) {
scanf("%d%d", &e[i].u, &e[i].v);
e[i].w = abs(val[e[i].u] - val[e[i].v]);
}
sort(e + , e + m + , cmp);
for (int i = ; i <= n; i++) fa[i] = i;
for (int i = ; i <= m; i++) {
int x = find(e[i].u), y = find(e[i].v);
if (x == y) continue;
fa[x] = y; used[i] = ;
add(e[i].u, e[i].v);
add(e[i].v, e[i].u);
}
dfs(, );
for (int i = ; i <= n; i++) fa[i] = i;
for (int i = ; i <= m; i++) {
if (used[i]) continue;
int x = find(e[i].u), y = find(e[i].v);
while (x != y) {
if (d[x] < d[y]) swap(x, y);
g[x][] = max(g[x][], e[i].w);
fa[x] = f[x][]; x = find(x);
}
}
for (int i = ; i <= T; i++)
for (int j = ; j <= n; j++)
g[j][i] = max(g[j][i - ], g[f[j][i - ]][i - ]);
while (q--) {
int x, y;
scanf("%d%d", &x, &y);
if (find(x) != find(y)) printf("infinitely\n");
else printf("%d\n", lca(x, y));
} return ;
}
[JZOJ4899] 雪之国度的更多相关文章
- 【JZOJ4899】【NOIP2016提高A组集训第17场11.16】雪之国度
题目描述 雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路.雪之女王赋予了每一座城市不同的能量,其中第i座城 ...
- [51nod1743]雪之国度
雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路. 雪之女王赋予了每一座城市不同的能量,其中第i座城市被赋予 ...
- 【51nod1743】雪之国度(最小生成树+倍增)
点此看题面 大致题意: 给你一张无向连通图,其中每条边的边权为这条边连接的两点的权值之差.每次询问两点之间是否存在两条不重复的路径,若存在则输出这两条路径上最大值的最小值. 大致思路 这题显然就是要让 ...
- 【HHHOJ】NOIP2018 模拟赛(二十五) 解题报告
点此进入比赛 得分: \(100+100+20=220\)(\(T1\)打了两个小时,以至于\(T3\)没时间打了,无奈交暴力) 排名: \(Rank\ 8\) \(Rating\):\(+19\) ...
- NOIP2018赛前停课集训记(10.24~11.08)
前言 为了不久之后的\(NOIP2018\),我们的停课从今天(\(Oct\ 24th\))起正式开始了. 本来说要下周开始的,没想到竟提早了几天,真是一个惊喜.毕竟明天有语文考试.后天有科学考试,逃 ...
- 用FSM一键制作逐帧动画雪碧图 Vue2 + webpack
因为工作需要要将五六十张逐帧图拼成雪碧图,网上想找到一件制作工具半天没有找到,就自己用canvas写了一个. 写成之后就再没有什么机会使用了,因此希望有人使用的时候如果遇到bug了能及时反馈给我. 最 ...
- 将MPM雪模拟移植到Maya
同事实现了一个迪士尼的MPM雪模拟论文,我将其移植到Maya中 论文题目是 A material point method for snow simulation 代码在这里: https://git ...
- BZOJ 1006 【HNOI2008】 神奇的国度
题目链接:神奇的国度 一篇论文题--神奇的弦图,神奇的MCS-- 感觉我没有什么需要多说的,这里简单介绍一下MCS: 我们给每个点记录一个权值,从后往前依次确定完美消除序列中的点,每次选择权值最大的一 ...
- 原创:CSS3技术-雪碧图自适应缩放与精灵动画方案
花了一个礼拜完成了慕课网定制的七夕主题效果,其中有一个没实现好的功能,就是雪碧图的自适应缩放 ps: 以下实现都是基于移动端的处理 原图如下: 人物是采用的是雪碧图,通过坐标绝对数据取值 问题很明显, ...
随机推荐
- JSP开发机票预定系统 源码
开发环境: Windows操作系统开发工具:MyEclipse+Jdk+Tomcat6+Mysql数据库 运行效果图 源码及原文链接:https://javadao.xyz/forum.php?mod ...
- Java基础之三、类的特性和接口
类的派生.多态.抽象类.接口 1:派生-extends 派生就是继承已有类非私有的字段和方法等创建新的类,还可以添加.重写字段和方法: 在类的派生中,构造函数不可以被继承: 派生源的类-父类/基类/超 ...
- node中 package.json 文件说明
1.概述 每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称.版本.许可证等元数据).npm install命令根据这个配置文 ...
- Angular4.0环境搭建
1.安装nodejs 先装nodejs,如果你的电脑已经装过了,最好确认是比较新的版本,否则可能会出问题 下载地址:https://nodejs.org/en/download/ 安装过程很简单,一直 ...
- 折腾vue--使用vscode创建vue项目(二)
1.安装webpack npm install -g webpack 2.安装sass npm install --save-dev sass-loader npm install --save-de ...
- Django如何连接mysql
1.设置django的mysql驱动为pymysql 因为django默认的是使用MySqlDb连接mysql数据库,但是由于该模块不支持python3.4以上版本,所以使用pymysql模块 在项目 ...
- Linux中“没有可用的软件包XX,但是它被其他软件包引用”的解决方法
踩坑经历 今天刚在虚拟机上安装好了ubuntu系统,在执行sudo apt install net-tools 命令时报错"没有可用的软件包net-tools,但是它被其他软件包引用&quo ...
- 2019sdqdCSP-J游记
特别鸣谢:Miku -------------------------- 中午上了车,和ljx坐在一块.太阳是多么好啊,我们在看着刚出的tg题,cmz找不到了准考证,sbl在临时打印准考证 等到好不容 ...
- 深入理解 C/C++ sizeof() 运算符
过去有一段时间一直以为带个括号的 \(sizeof()\) 是 \(C/C++\) 的原生函数QAQ. 其实不然,\(sizeof\) 同位运算符(^|&~!)一样是一种单目运算符,作用于变量 ...
- [TJOI2008] 小偷
TJOI2008小偷 题目背景 一位著名的小偷进入了一个充满宝石的储藏室,这个储藏室是由一连串房间构成的,房间的标号从0开始,想进入第i个房间就必须从第i-1个房间进入,如图: 题目描述 上图为三个房 ...