您的位置:首页 > 其它

[JZOJ4622] 亚瑟王之宫

2016-07-13 15:27 141 查看

Description



Solution

一开始看这题感觉骑士跳的最短路径很难处理,后来发现其实直接跑Floyd就可以了。

然后我们暴力枚举选哪两个点,假设所有的骑士都往第一个点走。

然后我们现在要选一些点移到第二个点去。

那我们显然选 到第二个点的距离−到第一个点的距离最小的N2个移过去就好。

证明显然

Code

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
int f[405][405],n,m,num,al,fx[8][2]={{1,2},{-1,2},{1,-2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1}};
int a[205][2],b[205];
int wz(int x,int y)
{
return ((x-1)*m)+y;
}
int main()
{
cin>>num>>m>>n;
int i,j,k,l,p;
fo(i,1,num) scanf("%d%d",&a[i][0],&a[i][1]);
fo(i,1,n*m)
{
fo(j,1,n*m)
{
f[i][j]=1000000000;
}
}
fo(i,1,n)
{
fo(j,1,m)
{
fo(k,0,7)
{
int x1=i+fx[k][0],y1=j+fx[k][1];
if (x1>0&&y1>0&&x1<=n&&y1<=m) f[wz(i,j)][wz(x1,y1)]=1;
}
}
}
al=n*m;
fo(k,1,al)
{
fo(i,1,al)
{
f[i][i]=0;
fo(j,1,al)
{
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
}
int ans=1000000000;
fo(i,1,n)
{
fo(j,1,m)
{
fo(k,1,n)
{
fo(l,1,m)
{
int s=0;
if (i!=k||j!=l)
{
fo(p,1,num)
{
s+=f[wz(i,j)][wz(a[p][0],a[p][1])];
b[p]=-f[wz(i,j)][wz(a[p][0],a[p][1])]+f[wz(k,l)][wz(a[p][0],a[p][1])];
}
sort(b+1,b+num+1);
fo(p,1,num/2) s+=b[p];
ans=min(ans,s);
}
}
}
}
}
cout<<ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: