bzoj 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课【spfa】

洛谷的数据毒啊
把(i,j,k)作为一个点spfa,表示点(i,j)朝向k方向,然后向四个方向转移即可

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=105,inf=1e9,dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int n,sx,sy,tx,ty,dis[N][N][5];
char a[N][N];
bool v[N][N][5];
struct qwe
{
    int x,y,k;
    qwe(int X=0,int Y=0,int K=0)
    {
        x=X,y=Y,k=K;
    }
};
inline bool ok(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=n&&a[x][y]!='x';
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%s",a[i]+1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            if(a[i][j]=='A')
                sx=i,sy=j;
            if(a[i][j]=='B')
                tx=i,ty=j;
            for(int k=0;k<4;k++)
                dis[i][j][k]=inf;
        }//cerr<<sx<<" "<<sy<<"   "<<tx<<" "<<ty<<endl;
    queue<qwe>q;
    v[sx][sy][0]=1,v[sx][sy][1]=1,v[sx][sy][2]=1,v[sx][sy][3]=1;
    dis[sx][sy][0]=0,dis[sx][sy][1]=0,dis[sx][sy][2]=0,dis[sx][sy][3]=0;
    q.push(qwe(sx,sy,0)),q.push(qwe(sx,sy,1)),q.push(qwe(sx,sy,2)),q.push(qwe(sx,sy,3));
    while(!q.empty())
    {
        int x=q.front().x,y=q.front().y,k=q.front().k;
        q.pop();
        v[x][y][k]=0;
        for(int i=0;i<4;i++)
            if(ok(x+dx[i],y+dy[i])&&dis[x+dx[i]][y+dy[i]][i]>dis[x][y][k]+(k!=i))
            {
                dis[x+dx[i]][y+dy[i]][i]=dis[x][y][k]+(k!=i);
                if(!v[x+dx[i]][y+dy[i]][i])
                {
                    v[x+dx[i]][y+dy[i]][i]=1;
                    q.push(qwe(x+dx[i],y+dy[i],i));
                }
            }
    }
    // for(int i=1;i<=n;i++)
        // for(int j=1;j<=n;j++)
            // for(int k=0;k<4;k++)
                // cerr<<i<<" "<<j<<" "<<k<<" "<<dis[i][j][k]<<endl;
    printf("%d\n",min(min(dis[tx][ty][0],dis[tx][ty][1]),min(dis[tx][ty][2],dis[tx][ty][3])));
    return 0;
}
/*
3
.xA
...
Bx.
*/

猜你喜欢

转载自www.cnblogs.com/lokiii/p/9012250.html
今日推荐