1. 程式人生 > >HDU - 5721 Palace

HDU - 5721 Palace

The last trial Venus imposes on Psyche is a quest to the underworld. She is to take a box and obtain in it a dose of the beauty of Prosperina, queen of the underworld. 

There are nn palaces in the underworld, which can be located on a 2-Dimension plane with (x,y)(x,y) coordinates (where x,yx,y are integers). Psyche would like to find the distance of the closest pair of two palaces. It is the password to enter the main palace. 

However, the underworld is mysterious and changes all the time. At different times, exactly one of the nn palaces disappears. 

Psyche wonders what the distance of the closest pair of two palaces is after some palace has disappeared. 

Print the sum of the distance after every single palace has disappeared. 

To avoid floating point error, define the distance dd between palace (x1,y1)(x1,y1) and (x2,y2)(x2,y2) as d=(x1−x2)2+(y1−y2)2d=(x1−x2)2+(y1−y2)2.

 

Input

The first line of the input contains an integer TT (1≤T≤5)(1≤T≤5), which denotes the number of testcases. 

For each testcase, the first line contains an integers nn (3≤n≤105)(3≤n≤105), which denotes the number of temples in this testcase. 

The following nn lines contains nn pairs of integers, the ii-th pair (x,y)(x,y) (−105≤x,y≤105)(−105≤x,y≤105) denotes the position of the ii-th palace.

 

Output

For each testcase, print an integer which denotes the sum of the distance after every single palace has disappeared.

 

Sample Input

1
3
0 0
1 1
2 2

 

Sample Output

12

 

Hint

If palace $ (0,0) $ disappears,$ d = (1-2) ^ 2 + (1 - 2) ^ 2 = 2 $;

If palace $ (1,1) $ disappears,$ d = (0-2) ^ 2 + (0 - 2) ^ 2 = 8 $;

If palace $ (2,2) $ disappears,$ d = (0-1) ^ 2 + (0-1) ^ 2 = 2 $;

Thus the answer is $ 2 + 8 + 2 = 12 $。

 題目大意:給個n個點,每次刪除一個點後求最小點對的距離的平方和dist,最後輸出所有的dist總和

解題思路:平面分治最小點對的模板題,n箇中距離最小的兩個點會被計算n-2次,因為刪除除這兩點之外的其他點,最小點距還是這兩個點,所以只需在計算當刪除的是這兩個點中的其中一個點時剩餘點的最小點距

平面分治最小點對:https://mp.csdn.net/postedit/85268256

AC程式碼:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn=1e6;
const ll INF=1e18;
int X,Y;//最小兩個點的下標 
ll dis; //當前最小距離 
struct node{
	ll x,y;
	int id;
}a[maxn],term[maxn];
bool cmpx(node a,node b)
{
	return a.x<b.x;
}
bool cmpy(node a,node b)
{
	return a.y<b.y;
}
ll dist(node a,node b)
{
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
void minpairs(int left,int right,int opt)//opt表示刪除點的序號 
{
	if(left==right)
		return ;
	if(left+1==right)
	{
		if(a[left].id!=opt&&a[right].id!=opt)
		{
			if(dist(a[left],a[right])<dis)
			{
				dis=dist(a[left],a[right]);
				if(opt==-1)
				{
					X=a[left].id;
					Y=a[right].id; 
				}
			}
		}
		return ;
	}
	int mid=(left+right)/2;
	minpairs(left,mid,opt);
	minpairs(mid+1,right,opt);
	int i,j,k=0;
	for(i=left;i<=right;i++)
	{
		if(a[i].id!=opt&&abs(a[i].x-a[mid].x)<=dis)
			term[k++]=a[i];
	}
	sort(term,term+k,cmpy);
	for(i=0;i<k;i++)
	{
		for(j=i+1;j<k;j++)
		{
			if(term[j].y-term[i].y>dis)
				break;
			if(dist(term[j],term[i])<dis)
			{
				dis=dist(term[j],term[i]);
				if(opt==-1)
				{
					X=term[i].id;
					Y=term[j].id;
				}
			}
		}
	}
	return ;
}
int main()
{
	int t,n;
	scanf("%d",&t);
	while(t--)
	{
		ll ans=0;
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%lld%lld",&a[i].x,&a[i].y);
			a[i].id=i;
		}
		dis=INF;
		sort(a,a+n,cmpx);
		minpairs(0,n-1,-1);
		ans+=dis*(n-2);
		dis=INF;
		minpairs(0,n-1,X);
		ans+=dis;
		dis=INF;
		minpairs(0,n-1,Y);
		ans+=dis;
		printf("%lld\n",ans);
	}
	return 0;
}