codevs2059逃出克隆岛(传送门bfs)

/*
和普通的迷宫问题类似只是多了一个叫传送门的东西
对于传送门的处理:
每当跑到传送门就把其余所有传送门周围的点都入队
传送门之间不花费时间并且从不是传送门的点走到传送门
也不花费时间花费时间的(好像说了句废话.) 所以判断一下 
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<algorithm>
#define maxn 5010
using namespace std;
int n,m,v,f[maxn][maxn],num;
char s[maxn][maxn];
int xx[5]={0,0,0,1,-1};
int yy[5]={0,1,-1,0,0};
int sx,sy,ex,ey;
struct node
{
    int xi,yi;
    int V;
};
struct Node
{
    int xi,yi;
}door[510];
queue<node>q;
int main()
{
    scanf("%d%d%d",&n,&m,&v);
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        {
          cin>>s[i][j];
          if(s[i][j]=='Y')
            {
              sx=i;sy=j;
              s[i][j]='*';
            }
          if(s[i][j]=='C')
            {
              ex=i;ey=j;
              s[i][j]='*';
            }
          if(s[i][j]=='P')
            {
              num++;
              door[num].xi=i;
              door[num].yi=j;
            }
        }
    node tmp;
    tmp.xi=sx;
    tmp.yi=sy;
    tmp.V=0;
    q.push(tmp);
    f[sx][sy]=1;
    while(!q.empty())
      {
          node now=q.front();
          q.pop();
          int nx=now.xi;
          int ny=now.yi;
          if(s[nx][ny]=='*')//普通的点 只要周围的点入队 
            for(int i=1;i<=4;i++)
              {
                  int ox=nx+xx[i];
                  int oy=ny+yy[i];
                  if(ox>0&&ox<=n&&oy>0&&oy<=m&&f[ox][oy]==0&&s[ox][oy]!='#')
                    {
                        f[ox][oy]=1;
                        node tmep;
                        tmep.xi=ox;
                        tmep.yi=oy;
                        if(s[ox][oy]=='*')tmep.V=now.V+v;
                        else tmep.V=now.V;//判断是不是要+time 
                        q.push(tmep);
                        if(ox==ex&&oy==ey)
                        {
                            printf("%d",now.V);
                            return 0;
                    }
                }
            }
          if(s[nx][ny]=='P')//传送门单独处理 
            for(int i=1;i<=num;i++)//所有的传送门 当然也包括他自己 
              {
                  int nx=door[i].xi;
                  int ny=door[i].yi;
                  for(int j=1;j<=4;j++)
                    {
                      int ox=nx+xx[j];
                      int oy=ny+yy[j];
                      if(ox>0&&ox<=n&&oy>0&&oy<=m&&f[ox][oy]==0&&s[ox][oy]!='#')
                        {
                            f[ox][oy]=1;
                            node tmep;
                            tmep.xi=ox;
                            tmep.yi=oy;
                            if(s[ox][oy]=='*')tmep.V=now.V+v;
                            else tmep.V=now.V;
                            q.push(tmep);
                            if(ox==ex&&oy==ey)
                           {
                               printf("%d",now.V);
                              return 0;
                         }
                    }  
                }
            }
      }
    printf("screw you!");
    return 0;
}

 

posted @ 2016-05-10 17:56  一入OI深似海  阅读(302)  评论(0编辑  收藏  举报