https://loj.ac/problem/10015
题目描述
给出二维平面上的(n)个点,每个单位时间点都会向四个方向扩散,求经过多少时间所有点之间形成连通分量,即任两点间都有路径连通。
思路
首先(n)的范围比较小,只有(50),那么我们可以预处理出两点之间需要多少时间才能连通。然后我们就要确定何时会形成一个连通分量。显然,如果在(t)时间时恰好形成一个连通分量,那么(t)时间之后的时间都一定符合。所以我们可以二分答案,判断在(mid)时间时是否为连通分量。图连通性的判断可以用并查集维护。
代码
#include <bits/stdc++.h>
using namespace std;
struct Edge
{
int x,y;
}a[60];
int n,mp[60][60],fa[60];
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void f_union(int x,int y)
{
int fx=find(x),fy=find(y);
fa[fx]=fy;
}
bool check(int x)
{
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(mp[i][j]<=x*2)f_union(i,j);
int s=0;
/* for(int i=1;i<=n;i++)
printf("%d ",fa[i]);
printf("
");*/
for(int i=1;i<=n;i++)
if(fa[i]==i)s++;
// printf("%d
",s);
return s==1;
}
int main()
{
scanf("%d",&n);
if(n==1)printf("0");
else
{
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++)
mp[i][j]=mp[j][i]=abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y);
/* for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
printf("%d ",mp[i][j]);
printf("
");
}*/
int l=0,r=1e9;
while(l<r)
{
int mid=(l+r)>>1;
// cout<<l<<' '<<mid<<' '<<r<<endl;
if(check(mid))r=mid;
else l=mid+1;
}
printf("%d",r);
}
return 0;
}