Description
Input
output
答案
Sample Input
4 4 4
1 1
4 1
1 4
4 4
Sample Output
4
Data Constraint
R,C<=20,N<=200
Solution
乍一看感觉挺难,结果发现R,C只有20,乘起来也就400,
O(n3)
都不会爆。
于是可以预处理出两个点之间的最短距离(这里的最短距离都是指日字跳的)Floyd搞定。
然后枚举出两个会合点,对于每个点,按照它与两个点的距离差排序。前n/2个会合到第一个点,后n/2个会合到第二个点。
注意Floyd不要打错。
Code
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define N 300
#define h(i,j) ((i-1)*c+j)
using namespace std;
int n,r,c,map[410][410];
struct note{
int x,y;
};
note a[N],b[N];
bool cnt(note x,note y){return x.x<y.x;}
int main()
{
scanf("%d%d%d",&n,&r,&c);
fo(i,1,n) scanf("%d%d",&a[i].x,&a[i].y);
fo(i,1,400) fo(j,1,400) map[i][j]=100000000;
fo(i,1,r)
{
fo(j,1,c)
{
if(i+1<=r&&j+2<=c)map[h(i,j)][h(i+1,j+2)]=1;
if(j-2>0&&i+1<=r)map[h(i,j)][h(i+1,j-2)]=1;
if(i-1>0&&j+2<=c)map[h(i,j)][h(i-1,j+2)]=1;
if(i-1>0&&j-2>0)map[h(i,j)][h(i-1,j-2)]=1;
if(i+2<=r&&j+1<=c)map[h(i,j)][h(i+2,j+1)]=1;
if(j-1>0&&i+2<=r)map[h(i,j)][h(i+2,j-1)]=1;
if(i-2>0&&j+1<=c)map[h(i,j)][h(i-2,j+1)]=1;
if(j-1>0&&i-2>0)map[h(i,j)][h(i-2,j-1)]=1;
}
}
fo(k,1,r*c)
fo(i,1,r*c)
{
map[i][i]=0;
fo(j,1,r*c)
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
}
int ans=2147483647;
fo(i,1,r*c)
{
fo(j,1,r*c)
if(i!=j)
{
int jy=0;
fo(k,1,n)
{
b[k].x=(map[h(a[k].x,a[k].y)][i]-map[h(a[k].x,a[k].y)][j]);
b[k].y=k;
}
sort(b+1,b+1+n,cnt);
fo(k,1,n)
{
int l=b[k].y;
if (k<=n/2) jy=jy+map[h(a[l].x,a[l].y)][i];
else jy=jy+map[h(a[l].x,a[l].y)][j];
}
ans=min(ans,jy);
}
}
printf("%d",ans);
}