1671: [Usaco2005 Dec]Knights of Ni 骑士
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 416 Solved: 266
[ Submit][ Status][ Discuss]
Description
Bessie is in Camelot and has encountered a sticky situation: she needs to pass through the forest that is guarded by the Knights of Ni. In order to pass through safely, the Knights have demanded that she bring them a single shrubbery. Time is of the essence, and Bessie must find and bring them a shrubbery as quickly as possible. Bessie has a map of of the forest, which is partitioned into a square grid arrayed in the usual manner, with axes parallel to the X and Y axes. The map is W x H units in size (1 <= W <= 1000; 1 <= H <= 1000). The map shows where Bessie starts her quest, the single square where the Knights of Ni are, and the locations of all the shrubberies of the land. It also shows which areas of the map can be traverse (some grid blocks are impassable because of swamps, cliffs, and killer rabbits). Bessie can not pass through the Knights of Ni square without a shrubbery. In order to make sure that she follows the map correctly, Bessie can only move in four directions: North, East, South, or West (i.e., NOT diagonally). She requires one day to complete a traversal from one grid block to a neighboring grid block. It is guaranteed that Bessie will be able to obtain a shrubbery and then deliver it to the Knights of Ni. Determine the quickest way for her to do so.
Input
Output
Sample Input
Sample Output
中文题面有错
把“相邻的数字所对应的区域是相邻的……布在两个不同的行里”这句话去掉就好了
求出起点到所有点的最短路,再求出终点到所有点的最短路
然后暴力枚举每个灌木求个最短路之和的最小值
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
typedef struct
{
int x;
int y;
}Point;
Point now, temp, s[1000005];
queue<Point> q1, q2;
int dp1[1005][1005], dp2[1005][1005], a[1005][1005];
int dir[4][2] = {1,0,-1,0,0,-1,0,1};
int main(void)
{
int cnt, n, m, i, j, ans;
scanf("%d%d", &m, &n);
cnt = 0;
memset(a, -1, sizeof(a));
memset(dp1, 62, sizeof(dp1));
memset(dp2, 62, sizeof(dp2));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d", &a[i][j]);
if(a[i][j]==2)
{
now.x = i, now.y = j;
q1.push(now);
dp1[i][j] = 0;
}
if(a[i][j]==3)
{
now.x = i, now.y = j;
q2.push(now);
dp2[i][j] = 0;
}
if(a[i][j]==4)
s[++cnt].x = i, s[cnt].y = j;
}
}
while(q1.empty()==0)
{
now = q1.front();
q1.pop();
for(i=0;i<=3;i++)
{
temp.x = now.x+dir[i][0];
temp.y = now.y+dir[i][1];
if(a[temp.x][temp.y]==1 || a[temp.x][temp.y]==-1)
continue;
if(dp1[now.x][now.y]+1<dp1[temp.x][temp.y])
{
dp1[temp.x][temp.y] = dp1[now.x][now.y]+1;
q1.push(temp);
}
}
}
while(q2.empty()==0)
{
now = q2.front();
q2.pop();
for(i=0;i<=3;i++)
{
temp.x = now.x+dir[i][0];
temp.y = now.y+dir[i][1];
if(a[temp.x][temp.y]==1 || a[temp.x][temp.y]==-1)
continue;
if(dp2[now.x][now.y]+1<dp2[temp.x][temp.y])
{
dp2[temp.x][temp.y] = dp2[now.x][now.y]+1;
q2.push(temp);
}
}
}
ans = 1000005;
for(i=1;i<=cnt;i++)
ans = min(ans, dp1[s[i].x][s[i].y]+dp2[s[i].x][s[i].y]);
printf("%d\n", ans);
return 0;
}