【C++】「一本通 1.2 练习 2」扩散

【来源】

一本通题库-1437
LibreOJ-10015
计蒜客-T1882
vjudge

【题目描述】

一个点每过一个单位时间就会向 4 个方向扩散一个距离,如图所示:两个点 a 、b 连通,记作 e ( a , b ) e(a,b) e(a,b),当且仅当 a 、b 的扩散区域有公共部分。连通块的定义是块内的任意两个点 u、v 都必定存在路径 e ( u , a 0 ) , e ( a 0 , a 1 ) , … e ( a k , v ) e(u,a_0),e(a_0,a_1),…e(a_k,v) e(u,a0),e(a0,a1),e(ak,v)

给定平面上的 n 个点,问最早什么时候它们形成一个连通块。

在这里插入图片描述

【输入格式】

第一行一个数 n ,以下 n 行,每行一个点坐标。

【输出格式】

输出仅一个数,表示最早的时刻所有点形成连通块。

【样例输入】

2
0 0
5 5

【样例输出】

5

【数据范围】

对于 20 % 20\% 20% 的数据,满足 1 ≤ n ≤ 5 , 1 ≤ X i , Y i ≤ 50 1≤n≤5,1≤X_i,Y_i≤50 1n5,1Xi,Yi50

对于 100 % 100\% 100% 的数据,满足 1 ≤ n ≤ 50 , 1 ≤ X i , Y i ≤ 1 0 9 1≤n≤50,1≤X_i,Y_i≤10^9 1n50,1Xi,Yi109

【解析】

二分答案,并用并查集维护是否联通。
详细点说就是每次暴力枚举两个点,判断在当前时间是否联通,如果联通就在并查集里连接。

【代码】

#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define RI                 register int
#define re(i,a,b)          for(RI i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))

using namespace std;

typedef long long LL;

const int N=55;
const int inf=1e9;

struct Node {
    
    
	int x,y;
} a[N];

int n;
int fa[N];
int d[N][N];

inline int getfa(int x) {
    
    
	return fa[x]==x ? x : fa[x]=getfa(fa[x]);
}

inline int check(int x,int y) {
    
    
	int a=getfa(x),b=getfa(y);
	if(a==b) return 0;
	fa[a]=b;
	return 1;
}

inline void f(int l,int r) {
    
    
	if(l+1==r) {
    
    
		printf("%d\n",r);
		exit(0);
	}
	int mid=(l+r)>>1;	
	for(int i=1; i<=n; i++) fa[i]=i;
	int k=n;
	for(int i=1; i<=n; i++) for(int j=i+1; j<=n; j++)
		if(d[i][j]<=(mid<<1)) if(check(i,j)) k--;
	if(k==1) f(l,mid);
		else f(mid,r);
}

int main() {
    
    
	scanf("%d",&n);
	for(int i=1; i<=n; i++) scanf("%d%d",&a[i].x,&a[i].y);
	for(int i=1; i<=n; i++) for(int j=i+1; j<=n; j++)
		d[i][j]=d[j][i]=abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y);
	f(0,inf);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Ljnoit/article/details/105772823