题解 P2864 【[USACO06JAN]The Grove S】

· · 题解

这里发一下建墙法的题解:

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int x,y;
    node(){}//构造函数 。 
    node(int _x,int _y) : x(_x),y(_y){};
};
int n,m,u1,v1,u2,v2,s,ans;
int vis[60][60],dis[60][60];
int fx[8][2] = {0,-1,0,1,-1,0,1,0,-1,-1,-1,1,1,1,1,-1};//有8个方向可以走 。 
char a[60][60];
queue <node> q;//队列 。 
void bfs()
{
    q.push(node(u1,v1));
    vis[u1][v1] = 1;
    dis[u1][v1] = 0;
    while(!q.empty())
    {
        node t = q.front();q.pop();
        for(int k = 0;k < 8;k++)
        {
            int u = t.x + fx[k][0],v = t.y + fx[k][1];
            if(u >= 1 && u <= n && v >= 1 && v <= m && a[u][v] == '.' && !vis[u][v])//只有空地可以走 。 
            {
                vis[u][v] = 1;
                dis[u][v] = dis[t.x][t.y] + 1;//更新距离 。 
                q.push(node(u,v));
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++) scanf("%s",a[i] + 1);
    for(int i = 1;i <= n;i++)
    {
        for(int j = 1;j <= m;j++)
        {
            if(a[i][j] == '*') u1 = i,v1 = j;//记录起点 。 
            if(a[i][j] == 'X') u2 = i + 1,v2 = j;//记录最后一棵树的位置,准确地说是建第一堵墙的位置 。 
        }
    }
    for(int i = 1;i < 60;i++)
    for(int j = 1;j < 60;j++)
    dis[i][j] = 1e9;//因为后面要取min,所以要赋一个比较大的值 。 
    for(int i = u2;i <= n;i++) a[i][v2] = '|';//建墙,注意要一直建到底 。 
    bfs();
    ans = min(min(dis[u2][v2 - 1],dis[u2 - 1][v2 - 1]),dis[u2 + 1][v2 - 1]) + 1;//更新起点到墙的距离。 
    printf("%d",ans + dis[u2 - 1][v2 + 1] + 1);//最后输出答案即可 。 
    return 0;
}

/ 管理员大大求过,thanks /