1 条题解
-
0
自动搬运
来自洛谷,原作者为

封禁用户
None搬运于
2025-08-24 21:27:39,当前版本为作者最后更新于2018-02-07 11:14:19,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
这题我拿二分答案+并查集做的,就是不断的二分时间,然后就要检测在这个时间内能不能成功形成连通块,我们用并查集来做:要是两点之间的曼哈顿距离(就是横纵坐标的差值和)不超过时间的2倍(这个地方很坑,因为两个点都能扩散,所以相对的扩散速度会增倍),那么就说明两个点能在一起然后就拿并查集连边,最后如果只有一个连通块就说明该时间合法,就向左区间去二分。 代码如下:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int xs[51]; int ys[51];//坐标 int ints[51];//并查集 int find(int n){ if(ints[n]==n)return(n); return(ints[n]=find(ints[n])); } int main(){ int n; cin>>n; for(int i=0;i<n;i++)cin>>xs[i]>>ys[i]; int l=0,r=1000000000; int ans=0;//最终答案 while(l<=r){ int mid=(l+r)>>1;//二分答案 for(register int i=0;i<n;i++){ ints[i]=i; }//初始化并查集 for(register int i=0;i<n;i++){ for(register int j=i+1;j<n;j++){ int dis=abs(xs[i]-xs[j])+abs(ys[i]-ys[j]); if(dis<=mid*2){//能扩散到就连边 int aa=find(i),ab=find(j); if(aa!=ab)ints[aa]=ab; } } } int cnt=0;//连通块个数 for(register int i=0;i<n;i++){ if(ints[i]==i)cnt++; } if(cnt==1){ ans=mid; r=mid-1; }//只有一个连通块就更新答案向下查找 else{ l=mid+1; } } cout<<ans<<endl; return(0); }
- 1
信息
- ID
- 653
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者