首页 > 编程语言 >Gym 100959B Airports(Prim算法,曼哈顿距离变换,曼哈顿距离最大生成树)

Gym 100959B Airports(Prim算法,曼哈顿距离变换,曼哈顿距离最大生成树)

时间:2022-10-05 20:01:08浏览次数:76  
标签:Prim 曼哈顿 距离 rbegin int abs b1 b2 id

今天训练遇到了这样一个题:给出平面上的n(1e5)个点,求d的最大值,使得所有距离不小于d的点连边后,图是联通的。
显然可以转化为求最大生成树的最小边权。
一种办法是优化边数,跑kruskal,这个网上有很多题解。
但是今天比赛的时候想了一种奇怪的做法,写完才发现好像和prim差不多:
我们维护两个集合A和B,一开始把随便一个点加入到A集合,其他的点都在B集合,然后重复以下操作:
找到分别属于集合A和集合B的最远点对,将对应B集合中的点加入A集合,直到所有点都在A集合中
过程中遇到的最小边权就是要找的d
然后受到暑假前一道题目的启发

在这个题里x1,y1,x2,y2都是变量,我们只需要用set分别维护集合A和B中x+y和x-y的值,对8种可能的情况取max,并把对应B集合中的点加到A集合中即可。
时间复杂度是O(nlogn)的。

//
// Created by vv123 on 2022/10/5.
//
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e6 + 10, mod = 998244353;

struct point {
    int x, y, id;
} p[N];
class cmp1 {
public:
    bool operator()(const point& a, const point&b) const {
        if (a.x + a.y != b.x + b.y) return a.x + a.y < b.x + b.y;
        else return a.id < b.id;
    }
};
class cmp2 {
public:
    bool operator()(const point& a, const point&b) const {
        if (a.x - a.y != b.x - b.y) return a.x - a.y < b.x - b.y;
        else return a.id < b.id;
    }
};
int n;

int work() {
    int res = 1e18;
    set<point, cmp1> a1, b1;
    set<point, cmp2> a2, b2;
    a1.insert(p[1]); a2.insert(p[1]);
    for (int i = 2; i <= n; i++) {
        b1.insert(p[i]); b2.insert(p[i]);
    }
    for (int i = 2; i <= n; i++) {
        int mina1 = a1.begin()->x + a1.begin()->y;
        int maxa1 = a1.rbegin()->x + a1.rbegin()->y;
        int mina2 = a2.begin()->x - a2.begin()->y;
        int maxa2 = a2.rbegin()->x - a2.rbegin()->y;
        int minb1 = b1.begin()->x + b1.begin()->y;
        int maxb1 = b1.rbegin()->x + b1.rbegin()->y;
        int minb2 = b2.begin()->x - b2.begin()->y;
        int maxb2 = b2.rbegin()->x - b2.rbegin()->y;
        int mx1 = max({abs(mina1 - minb1), abs(mina1 - maxb1), abs(maxa1 - minb1), abs(maxa1 - maxb1)});
        int mx2 = max({abs(mina2 - minb2), abs(mina2 - maxb2), abs(maxa2 - minb2), abs(maxa2 - maxb2)});
        //if (max(mx1, mx2) < D) return false;
        int mx = max(mx1, mx2);
        res = min(res, mx);
        if (mx == mx1) {
            if (mx1 == abs(mina1 - minb1) || mx1 == abs(maxa1 - minb1)) {
                int id = b1.begin()->id;
                a1.insert(p[id]); a2.insert(p[id]);
                b1.erase(p[id]); b2.erase(p[id]);
            } else {
                int id = b1.rbegin()->id;
                a1.insert(p[id]); a2.insert(p[id]);
                b1.erase(p[id]); b2.erase(p[id]);
            }
        } else {
            if (mx2 == abs(mina2 - minb2) || mx2 == abs(maxa2 - minb2)) {
                int id = b2.begin()->id;
                a1.insert(p[id]); a2.insert(p[id]);
                b1.erase(p[id]); b2.erase(p[id]);
            } else {
                int id = b2.rbegin()->id;
                a1.insert(p[id]); a2.insert(p[id]);
                b1.erase(p[id]); b2.erase(p[id]);
            }
        }
    }
    return res;
}


signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> p[i].x >> p[i].y;
        p[i].id = i;
    }
    cout << work() << "\n";
    return 0;
}

标签:Prim,曼哈顿,距离,rbegin,int,abs,b1,b2,id
From: https://www.cnblogs.com/vv123/p/16756235.html

相关文章

  • ElasticSearch-7.10版本最新万字长文教程【距离搞懂ELK核心你只差这一片文章】
    ES万字长文教程​​一、认识ELK、ES​​​​1.什么是ELK?​​​​2.什么是ElasticSearch​​​​3.ElasticSearch下载安装教程​​​​二、索引的CRUD​​​​1.创建索引​​......
  • 二叉树的直径和最大距离问题
    二叉树的直径和最大距离问题作者:Grey原文地址:博客园:二叉树的直径和最大距离问题CSDN:二叉树的直径和最大距离问题二叉树的直径给定一棵二叉树,你需要计算它的直径长度......
  • 【ARC136E】Non-coprime DAG(分类讨论)
    Non-coprimeDAG题目链接:ARC136E题目大意有一个n个点的有向图,i有连向j的边当且仅当i<j而且gcd(i,j)>1。然后给你每个点的点权,你要选一些点,使得任意两个点之间......
  • 常见距离算法
    机器学习中有很多的距离计算公式,用于计算数据和数据之间的距离,进而计算相似度或者其他。1.欧式距离(EuclideanDistance)​ 欧式距离是最常见的距离度量方法。小学、初中、......
  • #yyds干货盘点# 面试必刷TOP101:编辑距离(一)
    1.简述:描述给定两个字符串str1和str2,请你算出将str1转为str2的最少操作数。你可以对字符串进行3种操作:1.插入一个字符2.删除一个字符3.修改一个字符。字符串长度满......
  • 【ML算法基础】马氏距离
       直观解释(x−μ)(\bold{x}-\bold{\mu})(x−μ)本质上是向量与平均值的距离。然后,将其除以协方差矩阵(或乘以协方差矩阵的逆数)。这实际上是多元变量的常规标......
  • 2022“杭电杯”中国大学生算法设计超级联赛(3)-K - Taxi -曼哈顿+二分
    K-Taxi题意开始给你n个点每个点的坐标\((x_i,y_i)\),权值\(w_i\),一共q次询问,每次询问给你一个点(qx,qy),求该点到前面某个点的距离的最大值是多少。两个点之间的距离定义......
  • Spring MVC primary!
    步骤:1.定义一个handler处理器,并且实现controller接口packagejk.handlers;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpSe......
  • LeetCode[2399. 检查相同字母间的距离]
    2399.检查相同字母间的距离classSolution{public:boolcheckDistances(strings,vector<int>&distance){vector<int>p[26];//首先我们定义一个......
  • 距离2022年国庆节还有多少天?距离国庆节倒计时天数用便签设置
    进入9月下旬,相信有不少网友都在期待着国庆节的到来,今年国庆节依旧是10月1日,并且10月1日-7日是为期七天的国庆假期,而10月的8日、9日这两天为调休时间,需要正常上班和学习。......