D - Swap Pass

先将所有\(a_i==i\)的点都直接去掉

考虑将\(i\)向\(a_i\)连边,那么就会形成一个个的环

考虑只有一个环的情况,那么我们任意固定一个点\(x\),一直交换\(a_x\)与\(a_{a_x}\)直到\(a_x==x\),因为所有所有边都交于一点,所以这肯定是合法的

但更普遍的情况是不止有一个环,那么我们考虑交换两个环之间的某两个点的\(a\),那么这样就可以将两个环合成一个大环,然后继续我们刚才的操作即可

但是有可能环与环之间的边与大环里连的边相交了,考虑如何解决

我们选择最左边的最下的点作为极点\(O\),然后将其余点根据极角排序

我们用相邻点连边来解决环与环之间的交换,这个可以用并查集维护

然后从极点进行大环的连边,这样显然不存在相交的边

#include<bits/stdc++.h>
#define pii pair<int,int>
#define pb push_back
using namespace std;
const int N=2e3+5;
struct node{
int x,y,a,id;
double angle;
bool operator < (const node &other) const{
return angle<other.angle;
}
}cn[N];
int n,tot,fa[N],to[N];
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void merge(int x,int y){
x=find(x),y=find(y);
fa[x]=y;
}
vector<pii> op;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
++tot,scanf("%d%d%d",&cn[tot].x,&cn[tot].y,&cn[tot].a),cn[tot].id=i;
if(cn[tot].a==i) --tot;
fa[i]=i;
}
if(tot==0) return puts("0"),0;
n=tot;
int st=1;
for(int i=2;i<=n;++i) if(cn[i].x<cn[st].x||(cn[i].x==cn[st].x&&cn[i].y<cn[st].y)) st=i;
swap(cn[1],cn[st]);
for(int i=2;i<=n;++i) cn[i].angle=atan2(cn[i].x-cn[1].x,cn[i].y-cn[1].y);
sort(cn+2,cn+n+1);
for(int i=1;i<=n;++i) merge(cn[i].id,cn[i].a);
for(int i=2;i<n;++i){
int a=find(cn[i].id),b=find(cn[i+1].id);
if(a!=b) merge(a,b),swap(cn[i].a,cn[i+1].a),op.pb({cn[i].id,cn[i+1].id});
to[cn[i].id]=i;
}
to[cn[1].id]=1,to[cn[n].id]=n;
while(cn[1].a!=cn[1].id){
int t=to[cn[1].a];
swap(cn[1].a,cn[t].a),op.pb({cn[1].id,cn[t].id});
}
printf("%d\n",op.size());
for(auto [x,y]:op) printf("%d %d\n",x,y);
return 0;
}

[CF1508D] Swap Pass的更多相关文章

  1. Swap in C C++ C# Java

    写一个函数交换两个变量的值. C: 错误的实现: void swap(int i, int j) { int t = i; i = j; j = t; } 因为C语言的函数参数是以值来传递的(pass ...

  2. c/c++和java达到swap不同功能

    首先我们来看看c/c++实施swap性能 void swap ( int & a, int & b) { int Temp; temp = a; a = b; b = temp; } ...

  3. 搞定C系语言的的swap

    http://www.cs.utsa.edu/~wagner/CS2213/swap/swap.html 原地址 Parameters, by value and by reference: Both ...

  4. 非阻塞同步算法与CAS(Compare and Swap)无锁算法

    锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...

  5. 63. Swap Nodes in Pairs && Rotate List && Remove Nth Node From End of List

    Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. For exam ...

  6. Bus Pass

    ZOJ Problem Set - 2913 Bus Pass Time Limit: 5 Seconds      Memory Limit: 32768 KB You travel a lot b ...

  7. swap分析及其使用

    什么是swap swap主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因为内存不够用而导致oom或者更致命的情况出现.当内存使用存在压力的时候,开始触发内存回收行为, ...

  8. 考虑实现一个不抛异常的swap

    Effective C++:参考自harttle land 类的swap实现与STL容器是一致的:提供swap成员函数, 并特化std::swap来调用那个成员函数. class Widget { p ...

  9. C++异常安全、copy and swap

    异常安全的代码是指,满足两个条件 1异常中立性 : 是指当你的代码(包括你调用的代码)引发异常时,这个异常 能保持原样传递到外层调用代码.(异常中立,就是指任何底层的异常都会抛出到上层,也就相当于是异 ...

  10. Linux临时增加swap空间

    linux临时增加swap空间:step 1: #dd if=/dev/zero of=/home/swap bs=1024 count=500000 注释:of=/home/swap,放置swap的 ...

随机推荐

  1. Linux® 容器

    是与系统其他部分隔离开的一系列进程.运行这些进程所需的所有文件都由另一个镜像提供,这意味着从开发到测试再到生产的整个过程中,Linux 容器都具有可移植性和一致性.因而,相对于依赖重复传统测试环境的开 ...

  2. Docker top 命令

    Docker 命令大全Docker 命令大全docker top :查看容器中运行的进程信息,支持 ps 命令参数.语法docker top [OPTIONS] CONTAINER [ps OPTIO ...

  3. 【服务器】Nodejs在局域网配置https访问

    [服务器]Node.js在局域网配置https访问 零.需求: 做一个局域网WebRTC视频聊天系统,需要用到HTTPS.因此,配置Node.js使其支持HTTPS访问. 一.解决 在线生成和证书 访 ...

  4. ro在xe10.3上的安装

    在学习研究RO. RO9.2.101.1295在xe10.3上安装遇到新问题.记录处理的办法: 没有采用执行exe安装的方法.而是采用复制源代码后编译安装. 1.把生成的bpl.dcp安装到默认目录, ...

  5. [开源] 分享一个自己开发的, 整合SMS/Mail/Telegram/微信四个平台的开源信息收发平台

    起因于已有的聚合信息发送平台无法满足自己的需求. 不支持我需要的平台,或不支持接收信息后进行处理,或不放心把涉及隐私的消息通过第三方平台发送 利用SMS发送短信(上一篇文章中分享的开源项目) 利用SM ...

  6. Chrome谷歌浏览器常用快捷键、开发技巧

    谷歌浏览器作为常用的开发工具,熟悉常用的快捷键,不仅方便快捷,也能间接提高不少工作效率.以下是谷歌浏览器常用快捷键和开发技巧. 标签页和窗口快捷键 1. Ctrl + n 打开新窗口 2. Ctrl ...

  7. VSCode输出框中文乱码问题

    vscode输出中文的时候,总是出现乱码.找了一个一劳永逸解决问题的方法,转载的,原教程地址:https://blog.csdn.net/a19990412/article/details/90270 ...

  8. Web前端入门第 39 问:细说 CSS position 定位布局

    CSS 的定位属性 position 可以把元素从文档流中拧出来,让其显示在其他位置. 但凡元素定位属性加身,元素位置便不再受文档流控制,这时候什么 flex.grid 都不好使了,定位的元素已然跳出 ...

  9. 聊聊SpringAI流式输出的底层实现?

    在 Spring AI 中,流式输出(Streaming Output)是一种逐步返回 AI 模型生成结果的技术,允许服务器将响应内容分批次实时传输给客户端,而不是等待全部内容生成完毕后再一次性返回. ...

  10. 开源的java内网穿透 - 维基代理(wiki-proxy)

    1.简介 维基代理(wiki-proxy).开源的java内网穿透项目. 技术栈:cdkjFramework(维基框架).JPA.Netty 遵循MIT许可,因此您可以对它进行复制.修改.传播并用于任 ...