被这道BFS不带权图的最短路水题卡了三天,提交了80次。。。。。。就这样弱成渣了。。。。。。。。
这道题其实思路很简单,先求出每个点到所有点的最短路,然后枚举集合点,枚举接国王的骑士,枚举接国王的点,算出需要的距离。
总距离=Min{所有骑士到集合点的距离和-接国王的骑士到集合点的距离+国王到骑士接他的点的距离+骑士到接国王点的距离+其实从接国王的点走到集合点的距离} (当然太朴素就铁定超时了)
然后开始处理各个细节。
首先求最短路,一开始脑子没动当然就想到用Dijkstra求(我有多沙茶。。。),当然O(v*v^2)铁定要超时啊,所以用heap+Dijkstra做了一下。。。果然还是超时。。。这时候我终于缓过神来,这是无权图啊!求无权图的最短路就从每一个点开始走一遍BFS就出来了啊!。。。
然后是枚举的问题,朴素枚举当然O(n^3)超时,然后观察到这个图最大是30*26,然后估计一下最远的骑士和国王,估算后发现接国王的点应该在国王周围5格内,(这题数据弱,2格内就可以AC了,或者2格是对的?)。然后就胡乱AC了。。。
(这是网上一大神的思路)
这题对我来说最大的收获就是知道memset(a,0x3f,sizeof(a))a的初值为十位数然而memset(a,10,sizeof(a))a的初值为9位数。
/*
ID:jinbo wu
LANG:C++
TASK:camelot
*/
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int d[8][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};
struct node
{
int x,y;
}kn[1000];
node king;
int r,c;
int dist[40][30][40][30];
bool vis[40][30];
int kdist[40][30];
int allk[40][30];
queue<pair<int,int> > q;
void bfs(int x,int y)
{
memset(vis,0,sizeof(vis));
vis[x][y]=1;
dist[x][y][x][y]=0;
q.push(make_pair(x,y));
while(!q.empty())
{
int kx=q.front().first;
int ky=q.front().second;
q.pop();
for(int i=0;i<8;i++)
{
int dx=kx+d[i][0];
int dy=ky+d[i][1];
if(dx>=0&&dx<r&&dy>=0&&dy<c&&!vis[dx][dy])
{
dist[x][y][dx][dy]=dist[x][y][kx][ky]+1;
vis[dx][dy]=1;
q.push(make_pair(dx,dy));
}
}
}
return ;
}
int main()
{
freopen("camelot.in","r",stdin);
freopen("camelot.out","w",stdout);
char a;
int b;
cin>>r>>c;
cin>>a>>b;
king.y=a-'A';
king.x=b-1;
int num=0;
while(cin>>a>>b)
{
kn[num].y=a-'A';
kn[num++].x=b-1;
}
memset(dist,10,sizeof(dist));
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
bfs(i,j);
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
kdist[i][j]=max(abs(king.x-i),abs(king.y-j));
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
for(int k=0;k<num;k++)
allk[i][j]+=dist[i][j][kn[k].x][kn[k].y];
int ans=INF;
if(!num)
{
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
ans=min(ans,kdist[i][j]);
}
else
{
for(int k=0;k<num;k++)
{
for(int i=king.x-2;i<king.x+2;i++)
for(int j=king.y-2;j<king.y+2;j++)
if(i>=0&&i<r&&j>=0&&j<c)
{
for(int n=0;n<r;n++)
for(int m=0;m<c;m++)
ans=min(ans,abs(allk[n][m]-dist[kn[k].x][kn[k].y][n][m]+dist[kn[k].x][kn[k].y][i][j]+kdist[i][j]+dist[i][j][n][m]));
}
}
}
cout<<ans<<endl;
}