[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: 以下实现都是基于移动端的处理 原图如下: 人物是采用的是雪碧图,通过坐标绝对数据取值 问题很明显, ...
随机推荐
- 选择排序 C++实现
实现思想: 1.寻找[i, n)区间里的最小值min ( i>= 0 ) 2.交换min和第i的数 ( i>= 0 ) #include <iostream> #include ...
- 关于MY Sql 查询锁表信息和解锁表
1.查询锁住表信息 show OPEN TABLES where In_use > 0; 2.查看进程 show processlist; 3.解开锁住的表 需要杀掉锁住表的相关进程Id. k ...
- java基础--------arraylist(动态数组)和linkedlist(双向链表)的区别
arraylist使用数组存储数据,所以这样存储的数据根据索引查询的数据速度快,但是新增或者删除元素时需要设计到位移操作,所以比较慢. linkedlist使用双向链表方式存储数据,每个元素都记录前后 ...
- Java操作RocketMQ
第一步:导入依赖 <dependency> <groupId>com.alibaba.rocketmq</groupId> <artifactId>ro ...
- 从 0 使用 SpringBoot MyBatis MySQL Redis Elasticsearch打造企业级 RESTful API 项目实战
大家好!这是一门付费视频课程.新课优惠价 699 元,折合每小时 9 元左右,需要朋友的联系爱学啊客服 QQ:3469271680:我们每课程是明码标价的,因为如果售价为现在的 2 倍,然后打 5 折 ...
- android中常用的布局管理器
Android中的几种常用的布局,主要介绍内容有: View视图 RelativeLayout 相对布局管理器 LinearLayout 线性布局管理器 FrameLayout ...
- 四种常用的通知类型(xml)
1.maven依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...
- HashMap初始化容量过程
集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生.在日常开发中,我们经常会像如下方式以下创建一个HashMap: Map&l ...
- 使用shell程序备份crontab中的.sh脚本文件
需求 线上环境有一些定时脚本(用crontab -l可查看当前用户的),有时我们可能会改这些定时任务的脚本内容.为避免改错无后悔药,需用shell实现一个程序,定时备份crontab中的.sh脚本文件 ...
- linq to sql 获取sql与参数添加到日志中
这里的linq to sql并未使用ef 主要有以下内容 1.新增 2.修改 3.删除 4.查询 1.新增,修改,删除获取sql语句通过DataContext.Log获取执行的sql语句 String ...