【问题描述】 在平面上有n个点,一个点每过一个单位时间就会向4个方向(上下左右)扩散一个距离,如下图所示: 两个点a和b连通,记作e(a,b),当且仅当a、b的扩散区域有公共部分。连通块的定义是块内的任意两个点u、v都必定存在路径e(u,a0),e(a0,a1),……e(ak,v)。给定平面上n个点的坐标,问最早什么时刻它们形成一个连通块。 【输入文件】 第一行一个数:n 下面n行,每行两个整数x,y,代表一个点的坐标。 【输出文件】 一个整数,表示最早的时刻所有点形成的连通块。 【样例输入】 2 0 0 5 5 【样例输出】 5 【数据规模】 对于20%的数据,满足1<=n<=5; 1<=x[i],y[i]<=50; 对于100%的数据,满足1<=n<=50;1<=x[i],y[i]<=10^9
题解: 本题略水,我用的是最小生成树的方法,其实,弗洛伊德也可以,就是找最小中的最大的,呵呵,说着难,上程序! 原程:C++语言: made by PaulInsider! #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> using namespace std; int a[51],n,q[51][2],w[51][51],ji=0,answer=0; bool used[51]={0}; int main() { freopen ("ppg.in","r",stdin); freopen ("ppg.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d%d",&q[i][0],&q[i][1]); } for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) { int temp2; temp2=(abs((double)q[i][0]-q[j][0])+abs((double)q[i][1]-q[j][1])); if (temp2%2==1) { w[i][j]=temp2/2+1; } else { w[i][j]=temp2/2; } } } a[0]=1; ji=1; used[1]=1; for (int k=1;k<n;k++) { int temp=2100000000; int temp1; for (int i=0;i<ji;i++) { int d=0; int c=2100000000; for (int j=1;j<=n;j++) { if (a[i]!=j&&!used[j]) { if (w[a[i]][j]<c) { c=w[a[i]][j]; d=j; } } } if (c<temp) { temp=c; temp1=d; } } if (temp>answer) { answer=temp; } a[ji]=temp1; used[temp1]=1; ji++; } cout<<answer; return 0; }
神牛飘过,水牛留步! ORZ CZB!
|