/* 和普通的迷宫问题类似只是多了一个叫传送门的东西 对于传送门的处理: 每当跑到传送门就把其余所有传送门周围的点都入队 传送门之间不花费时间并且从不是传送门的点走到传送门 也不花费时间花费时间的(好像说了句废话.) 所以判断一下 */ #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; }