题目描述
一个点每过一个单位时间就会向四个方向扩散一个距离,如图。
两个点a、b连通,记作e(a,b),当且仅当a、b的扩散区域有公共部分。连通块的定义是块内的任意两个点u、v都必定存在路径e(u,a0),e(a0,a1),…,e(ak,v)。给定平面上的n给点,问最早什么时刻它们形成一个连通块。
输入输出格式
输入格式:第一行一个数n,以下n行,每行一个点坐标。
【数据规模】
对于20%的数据,满足1≤N≤5; 1≤X[i],Y[i]≤50;
对于100%的数据,满足1≤N≤50; 1≤X[i],Y[i]≤10^9。
输出格式:一个数,表示最早的时刻所有点形成连通块。
输入输出样例
输入样例#1:
2 0 0 5 5
输出样例#1:
5
两点间连边,距离为曼哈顿距离
答案等于(int)(最小生成树上最长边+1)/2
敲kruskal的时候居然漏掉了x=find(x)
因为写太快漏掉了吗?恐怕是因为那个瞬间没有走心
那样的瞬间还会出现多少次呢?
誰も知らない
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const int mxn=60; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 struct edge{ 17 int x,y; 18 int d; 19 }e[mxn*mxn]; 20 int mct=0; 21 int cmp(edge a,edge b){ 22 return a.d<b.d; 23 } 24 struct point{ 25 int x,y; 26 }a[mxn]; 27 int fa[mxn]; 28 int find(int x){ 29 if(fa[x]==x)return x; 30 return fa[x]=find(fa[x]); 31 } 32 int dist(int x,int y){ 33 return abs(a[x].x-a[y].x)+abs(a[x].y-a[y].y); 34 } 35 //int mp[mxn][mxn]; 36 int n,ans=0; 37 void solve(){ 38 int i,j; 39 for(i=1;i<=n;i++)fa[i]=i; 40 int num=1; 41 for(i=1;i<=mct;i++){ 42 int x=e[i].x; 43 int y=e[i].y; 44 x=find(x);y=find(y); 45 if(x!=y){ 46 ans=max(ans,e[i].d); 47 num++; 48 fa[x]=y; 49 } 50 if(num==n)break; 51 } 52 return; 53 } 54 int main(){ 55 int i,j; 56 n=read(); 57 for(i=1;i<=n;i++){ 58 a[i].x=read(); 59 a[i].y=read(); 60 } 61 for(i=1;i<n;i++) 62 for(j=i+1;j<=n;j++){ 63 e[++mct].x=i;e[mct].y=j; 64 e[mct].d=dist(i,j); 65 } 66 sort(e+1,e+mct+1,cmp); 67 // 68 solve(); 69 printf("%d\n",(ans+1)/2); 70 return 0; 71 }