首页 > 其他分享 >[CF1422D] Returning Home 题解

[CF1422D] Returning Home 题解

时间:2022-12-20 23:44:53浏览次数:43  
标签:dist Returning int 题解 横坐标 leq heap Home include

题目描述

一个\(n \times n\)的网格,求两点间最短用时。

你可以用一分钟向上下左右任意一个方向移动一格.特别的,城市中有\(m\)个传送点,第\(i\)个的坐标为\((x_{i},y_{i})\).当你与一个传送点横坐标相同或纵坐标相同,那么你就可以瞬间传送到该传送点.

求到达目的地的最短用时.

\(1 \leq n \leq 10^9,1 \leq m \leq 10^5,1 \leq s_{x},s_{y},f_{x},f_{y},x_{i},y_{i} \leq n\).

想法

首先看到数据范围,发现 \(n \leq 10^9\),这就代表我们绝对不可能把所有的点存下来,但是与之相比 \(m \leq 10^5\) 就很友好了,于是从关键点 \(m\) 破题。

考虑把 \(m\) 个点在新图中建出来,那么现在我们就缺边了。

有一种朴素的想法是每两个点之间都连一条边,空间复杂度 \(O(m^2)\),会爆掉。

如何进行优化呢?

其实原图中有些边是用不到的,比如:

image-20221220231859692

在这样一张图中,红蓝绿点两两连边,其中蓝色的边在横坐标意义上是冗余的,因为此时红点到蓝点可以选择 \(红\rightarrow 绿 \rightarrow 蓝\) 这条路径到达蓝点,而由于题目的特殊性质,这条路径其实是与原边等价的,我们只保留路径就好了。

或者更进一步地,我们说,一条边在横坐标意义上不是冗余的,当且仅当他连接的两点横坐标间没有其他点,纵坐标同理。

也许有人不理解何为横纵坐标意义下。

image-20221220232752741

取一个极端的例子,这时这条边 \(绿\rightarrow 黄\) 无论是横坐标还是纵坐标来看都是冗余的,都可以被其他路径等效替代。

思路

由此萌发思路:只连接横坐标相邻的两点与纵坐标相邻的两点。

这时连边空间复杂度就是 \(O(m)\) 量级的。

实现

分别以点的 \(x,y\) 坐标为关键字排序,连接相邻的点即可。

实现的时候需要另外连起点到所有特殊点,与所有特殊点到终点的特殊边。

Trick: 以 \(0\) 和 \(m + 1\) 编号起点和终点。

照常 \(\text{Dijkstra}\),时间复杂度 \(O(m\log n)\)。

// Problem: Returning Home
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF1422D
// Memory Limit: 250 MB
// Time Limit: 2000 ms
// Author: Moyou
// Copyright (c) 2022 Moyou All rights reserved.
// Date: 2022-12-20 22:18:46

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#define x first
#define y second
#define int long long
#define INF 1e18
using namespace std;
typedef pair<int, int> PII;

const int N = 2e5 + 10, M = (N << 3);

struct node
{
    int id;
    int x, y;
} a[N];

int h[N], ne[M], e[M], w[M], idx;
void add(int a, int b, int c)
{
    e[++idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx;
}

int calc(PII a, PII b)
{
    return abs(a.x - b.x) + abs(a.y - b.y);
}

int n, m;
int dist[N];
bool st[N];
int dijkstra(int s)
{
    for (int i = 0; i <= m + 1; i++)
        dist[i] = INF, st[i] = 0;
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    heap.push({0, s});
    dist[s] = 0;
    while (heap.size())
    {
        auto t = heap.top().y;
        heap.pop();
        if (st[t])
            continue;
        st[t] = 1;
        for (int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                heap.push({dist[j], j});
            }
        }
    }
    return dist[m + 1];
}

signed main()
{
    memset(h, -1, sizeof h);
    cin >> n >> m >> a[0].x >> a[0].y >> a[m + 1].x >> a[m + 1].y;
    a[0].id = 0, a[m + 1].id = m + 1;

    for (int i = 1; i <= m; i++)
        cin >> a[i].x >> a[i].y, a[i].id = i;

    add(0, m + 1, calc({a[0].x, a[0].y}, {a[m + 1].x, a[m + 1].y}));
    for (int i = 1; i <= m; i++)
    {
        add(0, i, min(abs(a[0].x - a[i].x), abs(a[0].y - a[i].y)));
        add(i, m + 1, abs(a[m + 1].x - a[i].x) + abs(a[m + 1].y - a[i].y));
    }

    sort(a + 1, a + m + 1, [](node a, node b) { return a.x < b.x; });
    for (int i = 1; i < m; i++)
        add(a[i].id, a[i + 1].id, a[i + 1].x - a[i].x), add(a[i + 1].id, a[i].id, a[i + 1].x - a[i].x);

    sort(a + 1, a + m + 1, [](node a, node b) { return a.y < b.y; }); // Lambda表达式,作用等同cmp函数
    for (int i = 1; i < m; i++)
        add(a[i].id, a[i + 1].id, a[i + 1].y - a[i].y), add(a[i + 1].id, a[i].id, a[i + 1].y - a[i].y);

    cout << dijkstra(0) << endl;
    return 0;
}

标签:dist,Returning,int,题解,横坐标,leq,heap,Home,include
From: https://www.cnblogs.com/MoyouSayuki/p/16995366.html

相关文章

  • USACO 2022 Dec 铂金组题解
    有生之年终于AK一次Pt组了,发个题解玩玩。T1-Breakdown大部分情况下,题目里若存在一个很小的\(k\)这样的角色,都是因为它在复杂度指数上(包括但不限于\(2^{\operato......
  • HttpClient Timeout waiting for connection from pool 问题解决方案
    错误:org.apache.http.conn.ConnectionPoolTimeoutException:Timeoutwaitingforconnectionfrompool前言:第一次看到这个错误,上网找了下,有文章说是连接池不够了。。。......
  • MYSQL问题解决
    1、MySQL错误日志里出现:14033110:08:18[ERROR]Errorreadingmasterconfiguration14033110:08:18[ERROR]Failedtoinitializethemasterinfostructure14033110:......
  • Codeforces 1763 F Edge Queries 题解
    题目链接先观察满足题目中给出的限制的图有什么特点。先看\(C_u\),它指的是所有与\(u\)在同一个简单环内的节点。发现一个点v在\(C_u\)中,当且仅当\(u,v\)点双连通。关于点......
  • git相关问题解析,你想要的都有
    官网文档:https://git-scm.com/doc本地克隆远程代码仓库gitclone地址本地同步全量历史数据,克隆所有文件的历史记录gitclone地址—depth1本地同步默认分支......
  • CF1344D 题解
    题意传送门给定一个长度为\(n\)的数组\(a_i\),构造自然数数组\(b_i\)满足:\(\foralli,b_i\in[0,a_i]\)\(\sum_{i=1}^nb_i=k\)并最大化\(\sum_{i=1}^nb_i(a......
  • 关于XML文件运行一段时间后,发现程序加载XML文件的时候报错问题解决方法
    一、问题描述程序所使用的XML文件运行一段时间后,发现程序加载XML文件的时候报错,要么XML内容被清空,要么就是内容少了一些,节点不完整,不是有效的XML文件。二、问题分析针对......
  • P1314 聪明的质监员(题解)
    题目小T是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有\(n\)个矿石,从\(1\)到\(n\)逐一编号,每个矿石都有自己的重量\(w_i\)以及价值\(v_i\)。检验......
  • NOIP2022题解
    \(\mathbf{NOIP2022}\)\(\mathbf{plant}\)\(\mathbf{Describe}\)题面\(\mathbf{Solution}\)我们记\(f(x,y)\)表示从\((x,y)\)向右连续的\(0\)段的长度,\(up_......
  • NOIP2022 游记 & 简要题解
    游.寄\(\text{Day0}\)由于疫情的原因,原本预定的团建活动鸽了,于是就在机房里放送起来,打了一天的三国杀,身份、国战都打了。中午教练请吃饭,吃到了来一中之后最好的一餐。......