[TCO2014 3B]OnePointNineNine

题目大意

现在平面上有n个点,已知有一个常数D。
任意两点的距离要么<=D,要么>=1.99D。
请问有多少点集的子集,满足任意两点距离>=1.99D。

n<=1000。

解法

我们肯定是把距离<=D的点对连边。然后相当于独立集计数。
可以考虑把等价点缩在一起:
两个点如果它们之间有连边,然后其余连边完全相同,则显然该两点等价。
即{u}or{u的邻居}={v}or{v的邻居}
接下来有一个结论:
缩完点后每个联通块都是环或链(即每个点度数不超过2)。
那么对每个联通块DP即可。
如何证明结论?

证明

首先,如果对于两个点u和v,|uv|<0.99D,它们一定等价。
因为这两个点一定有连边,然后对于一个其他点w,如果u与w有边,则|uw|<=D,根据不等式|vw|<=|vu|+|uw|<1.99D,因此v与w也一定会有边。
那么,缩点后的图,每条边的长度均在[099D,D]。
接下来我们来反证不会出现度数为3的点。
假设一个点连接了三个邻居。
任意两个邻居间距离要么<=D,要么>=1.99D。
每个邻居距离该点都在[0.99D,D]间。
不妨用余弦定理解出角度的范围。
如果两个邻居距离>=1.99D,那么角度范围在180度往下一点。
如果两个邻居距离<=D,那么角度范围在60度左右。
如果没有邻居间有边,加起来下界爆了360度。
如果有一对有边,也爆了360度。
两对有边达不到360度,三对有边同理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值