Luogu 4473 [国家集训队]飞飞侠
BZOJ 2143
新技能:并查集优化最短路。
暴力最短路是$O(n^4)$的,然后拿个线段树优化一下连边就$O($能过$)$了。
但是这样都太慢了。
我们考虑一个点如果之前被更新过了,那么之后就不会被更新了,所以我们只要能跳过这个已经被更新过的点,直接去更新没有更新过的点就行了,刚好对应了一个并查集的路径压缩,这样子每一次跳到一个没有更新过的点就是$O(1)$的了。
每一个点拿出来的更新的时候其实是要付出它的点权,所以我们要把$dis_{x, y} + a_{x, y}$一起丢到堆里去才能保证转移的正确性。
还是不会算时间复杂度,但是非常优秀。
Code:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll; const int N = ;
const ll inf = 0x3f3f3f3f3f3f3f3f; int n, m, b[N][N], ufs[N][N], sx[], sy[];
ll a[N][N], dis[N][N], ans[];
bool vis[N][N]; struct Node {
int x, y;
ll d; inline Node (int nowX = , int nowY = , ll nowD = 0LL) {
x = nowX, y = nowY, d = nowD;
} friend bool operator < (const Node &u, const Node &v) {
return u.d > v.d;
} };
priority_queue <Node> Q; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline int max(int x, int y) {
return x > y ? x : y;
} inline int min(int x, int y) {
return x > y ? y : x;
} inline int abs(int x) {
return x > ? x : -x;
} int find(int x, int y) {
return ufs[x][y] == y ? y : ufs[x][y] = find(x, ufs[x][y]);
} void dij(int st) {
for(int i = ; i <= n; i++)
for(int j = ; j <= m + ; j++) {
dis[i][j] = inf;
ufs[i][j] = j;
vis[i][j] = ;
}
dis[sx[st]][sy[st]] = 0LL;
Q.push(Node(sx[st], sy[st], a[sx[st]][sy[st]]));
ufs[sx[st]][sy[st]] = sy[st] + ;
for(; !Q.empty(); ) {
Node out = Q.top(); Q.pop();
int x = out.x, y = out.y;
if(vis[x][y]) continue;
vis[x][y] = ; int ln = max(, x - b[x][y]), rn = min(n, x + b[x][y]);
for(int i = ln; i <= rn; i++) {
int stp = b[x][y] - abs(i - x);
int lm = max(, y - stp), rm = min(m, y + stp);
for(int j = find(i, lm); j <= rm; j = find(i, j)) {
if(dis[i][j] > dis[x][y] + a[x][y]) {
dis[i][j] = dis[x][y] + a[x][y];
Q.push(Node(i, j, dis[i][j] + a[i][j]));
}
ufs[i][j] = j + ;
}
}
}
} int main() {
freopen("4.in", "r", stdin);
// freopen("my.out", "w", stdout); read(n), read(m);
for(int i = ; i <= n; i++)
for(int j = ; j <= m; j++)
read(b[i][j]);
for(int i = ; i <= n; i++)
for(int j = ; j <= m; j++)
read(a[i][j]); for(int i = ; i <= ; i++)
read(sx[i]), read(sy[i]); for(int i = ; i <= ; i++) {
dij(i);
for(int j = ; j <= ; j++) ans[j] += dis[sx[j]][sy[j]];
} ll res = inf, pos = ;
for(int i = ; i <= ; i++)
if(ans[i] < res) res = ans[i], pos = i; if(res >= inf) {
puts("NO");
return ;
} if(pos == ) puts("X");
if(pos == ) puts("Y");
if(pos == ) puts("Z"); printf("%lld\n", res);
return ;
}
Luogu 4473 [国家集训队]飞飞侠的更多相关文章
- luogu4473 BZOJ2143 2011[国家集训队]飞飞侠
题目戳这里 有问题可以在博客@ 应该还会有人来看吧,嘻嘻 正题: 题目大意: 题目很清楚,就是一个点有一定的范围,会有一定的花费 求三个点中的任意两个点到另一个点的最小花费 (麻麻教育我千万读好题目( ...
- luogu P2757 [国家集训队]等差子序列
题目链接 luogu P2757 [国家集训队]等差子序列 题解 线段树好题 我选择暴力 代码 // luogu-judger-enable-o2 #include<cstdio> inl ...
- luogu P2619 [国家集训队2]Tree I
题目链接 luogu P2619 [国家集训队2]Tree I 题解 普通思路就不说了二分增量,生成树check 说一下坑点 二分时,若黑白边权有相同,因为权值相同优先选白边,若在最有增量时出现黑白等 ...
- [Luogu P1829] [国家集训队]Crash的数字表格 / JZPTAB (莫比乌斯反演)
题面 传送门:洛咕 Solution 调到自闭,我好菜啊 为了方便讨论,以下式子\(m>=n\) 为了方便书写,以下式子中的除号均为向下取整 我们来颓柿子吧qwq 显然,题目让我们求: \(\l ...
- Luogu P1297 [国家集训队]单选错位
P1297 [国家集训队]单选错位 题目背景 原 <网线切割>请前往P1577 题目描述 gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案.试卷上 ...
- Luogu P2619 [国家集训队2]Tree I(WQS二分+最小生成树)
P2619 [国家集训队2]Tree I 题意 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有\(need\)条白色边的生成树. 题目保证有解. 输入输出格式 输入格式 ...
- 【luogu P1494 [国家集训队]小Z的袜子】 题解
题目链接:https://www.luogu.org/problemnew/show/P1494 #include <cstdio> #include <algorithm> ...
- 【luogu P1903 [国家集训队]数颜色】 题解
题目链接:https://www.luogu.org/problemnew/show/P1903 裸的...带修莫队... 比较麻烦吧(对我来说是的) 两个变量分开记录查询和修改操作. #includ ...
- BZOJ 2127 / Luogu P1646 [国家集训队]happiness (最小割)
题面 BZOJ传送门 Luogu传送门 分析 这道题又出现了二元关系,于是我们只需要解方程确定怎么连边就行了 假设跟SSS分在一块是选文科,跟TTT分在一块是选理科,先加上所有的收益,再来考虑如何让需 ...
随机推荐
- Python学习-list操作
Python列表(list)操作: 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置 ...
- Protobuf-net 应用
什么是ProtoBuf-net Protobuf是google开源的一个项目,是基于二进制的类似于XML,JSON这样的数据表示语言,用户数据序列化反序列化,google声称google的数据通信都是 ...
- C#合成解析XML与JSON
http://www.xuanyusong.com/archives/1901 XML与JSON在开发中非常重要, 其实核心就是处理字符串.一个是XML的字符串一个是JSON的字符串,尤其是在处 ...
- android jUnit test 进行自动化测试
一. 被test的工程: 新建一个android工程:D_session:它有一个activity:D_sessionActivity:package名:com.mysession 二.测试工程: 新 ...
- Voting and Shuffling to Optimize Atomic Operations
2iSome years ago I started work on my first CUDA implementation of the Multiparticle Collision Dynam ...
- 蓝桥杯 算法训练 ALGO-93 反置数
算法训练 反置数 时间限制:1.0s 内存限制:512.0MB 问题描述 一个整数的“反置数”指的是把该整数的每一位数字的顺序颠倒过来所得到的另一个整数.如果一个整数的末尾是以0结尾,那么在它 ...
- C# VS Java
摘要:C#的语言规范由Microsoft的Anders Hejlsberg与Scott Wiltamuth编写.在当前Microsoft天花乱坠的宣传中,对C#和C++.Java作一番比较总是很有趣的 ...
- Python if-elif-else
alien_color = ['green','yellow','red']for color in alien_color: if color == 'green': print 'alien_co ...
- Py修行路 python基础 (五)三元运算 字符编码 元组 集合 三级菜单优化!
三元运算 条件判断不能加冒号: a=3 b=5 c=a if a<b else b oct() 转成八进制的简写:16进制 标志:BH为后缀或是0x为前缀hex() 转成16进制 元组 跟列表是 ...
- Patator-一款很好用的爆破工具
项目地址:https://github.com/lanjelot/patator 打开文件夹 运行一下文件查看帮助 python patator.py --help 这里有很多的爆破选项,就不一一截图 ...