【GDOI2018模拟7.6】仰望星空
来源:互联网 发布:国企混日子 知乎 编辑:程序博客网 时间:2024/04/27 14:59
Description
由于原题看了好多遍才真正理解题意,这里讲一个简化版本
给出平面上的一个圆和n个点
现在要再这n个点之间两两连边
每个点只能被连一次,只有圆内和圆外之间距离不超过d的点可以互相连边
且如果存在三个圆内的未被连边的点x,y,z,与圆外一点w的距离不超过d
现在若想连接w和y,并且x与z的连线与w,y的连线相交,那么这个连线是不合法的
求最大的连线数目和方案
n<=1e3
Solution
显然最大匹配
考虑怎么处理这个鬼畜的限制
发现执行匈牙利算法的时候我们每个点都会按顺序匹配
于是我们队每个圆外的点,将圆内的点关于它做一次极角排序,得到它的遍历顺序
然后直接做匈牙利就可以解决这个神奇的限制得到答案
注意方案必须要按顺序,所以每个点必须等它之前的匹配全部输出之后才能输出
并不知道atan2用来极角排序哪里错了
bool cmp(point a,point b) {return atan2(a.y-rt.y,a.x-rt.x)<atan2(b.y-rt.y,b.x-rt.x);}
改成叉积就对了,求dalao解释
bool cmp(point a,point b) {return cro(a,b,rt)>0;}
UPD:错因很显然然而我现在才发现一定是我太弱了_ (:з」∠) _
这道题排极角序必须是严格按顺序,不能有一个起点
然而用atan2就默认第3象限最小,这样会有问题
Code
#include <cmath>#include <cstdio>#include <cstring>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define sqr(x) (x)*(x)using namespace std;typedef double db;const int N=1e3+5;int n,r,d,tot,ans,b[N],c[N],g[N][N],to[N],link[N];db eps=1e-5;bool vis[N],bz[N];struct point{int x,y,id;}a[N],p[N],rt;int cro(point a,point b,point x) {return (a.x-x.x)*(b.y-x.y)-(a.y-x.y)*(b.x-x.x);}db dist(point a,point b) {return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}bool cmp(point a,point b) {return cro(a,b,rt)>0;}int find(int x) { fo(i,1,g[x][0]) if (!vis[g[x][i]]) { vis[g[x][i]]=1; if (!to[g[x][i]]||find(to[g[x][i]])) { to[g[x][i]]=x; return 1; } } return 0;}int main() { freopen("B.in","r",stdin); scanf("%d%d%d",&n,&r,&d); fo(i,1,n) scanf("%d%d",&a[i].x,&a[i].y),a[i].id=i; fo(i,1,n) { if (dist(a[i],a[1])-r<eps) b[++b[0]]=i; else c[++c[0]]=i; } fo(i,1,c[0]) { tot=0;rt=a[c[i]]; fo(j,1,b[0]) if (dist(a[b[j]],a[c[i]])-d<eps) p[++tot]=a[b[j]]; sort(p+1,p+tot+1,cmp);int x=a[c[i]].id; fo(j,1,tot) g[x][++g[x][0]]=p[j].id; } fo(i,1,c[0]) { memset(vis,0,sizeof(vis)); ans+=find(a[c[i]].id); } printf("%d\n",ans*2); fo(i,1,b[0]) link[to[a[b[i]].id]]=a[b[i]].id; fo(i,1,ans) { bool pd=0;int now=0; fo(j,1,c[0]) { int x=a[c[j]].id; fo(k,1,g[x][0]) if (!bz[g[x][k]]) { if (g[x][k]==link[x]) pd=1; now=g[x][k];break; } if (pd) { bz[now]=1; printf("%d %d\n",x,now); break; } } }}
阅读全文
1 0
- 【GDOI2018模拟7.6】仰望星空
- 【JZOJ 5205】【GDOI2018模拟7.6】仰望星空
- 仰望星空
- 仰望星空
- 仰望星空
- 【GDOI2018模拟7.6】吃干饭
- 诗欣赏《仰望星空》
- 仰望星空与脚踏实地
- 仰望星空不如脚踏实地
- 脚踏实地,仰望星空
- 仰望星空-昨夜星思
- 【年终总结】—仰望星空,脚踏实地
- 【JZOJ 5204】【GDOI2018模拟7.6】吃干饭
- 撑不下去的时候,仰望,星空。
- 梦想与行动:仰望星空,脚踏实地
- 【GDOI2018模拟7.9】期末考试
- 【GDOI2018模拟7.8】质数
- 【GDOI2018模拟7.8】矩阵
- Android ContentProvider理解与实践
- cmd NTSD命令用法详解
- Android SSO 相关文章
- LCA的tarjan算法--总结
- Android 多线程下载实现思路
- 【GDOI2018模拟7.6】仰望星空
- sparql 查询例子
- oozie安装失败SERVER[cdh.master.linesum] E0103:
- 序列化加密/反序列化解密
- 文献记录《Light Field Stitching for Extended Synthetic Aperture》
- php pack、unpack、ord 函数使用方法(二进制流接口应用实例)[转载]
- ubuntu下配置tftp服务器
- Android的SeekBar进度详解和进度系列控件自定义
- 操作DOM树基础知识