11.codevs 2059逃出克隆岛
题目大意:N行M列的矩阵,’Y’表示yh的出生位置,C表示克隆岛的出口,’#’表示该处不可通过,’*’表示通过该处需要消耗金币cost, ’P’表示传送阵,任意两个传送阵之间可以免费互相传送。求从’Y’出发到’C’最少需要消耗多少金币
分析:此题关键在于任意两个传送门可以互相免费传送,有因为求最少消耗的金币,所以用bfs
只需先预处理出t[a][b]表示a到b有传送门,即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
char g[5005][5005];
int dx[] = {0,0,1,-1},dy[] = {1,-1,0,0},vis[5005][5005],n,m,cost,cnt,t[505][2],ans = 0x3f3f3f3f;
struct node
{
int x,y,co;
bool operator < (const node &a) const
{
return co > a.co;
}
}st;
priority_queue <node> q;
void bfs(node s)
{
q.push(s);
vis[s.x][s.y] = 1;
while(!q.empty())
{
node now = q.top();
q.pop();
for(int i = 0; i <= 3; ++i)
{
node nt = now;
nt.x += dx[i];
nt.y += dy[i];
if(g[nt.x][nt.y] == '#' || nt.x < 0 || nt.y < 0 || nt.x >= n || nt.y >= m || vis[nt.x][nt.y]) continue;
if(g[nt.x][nt.y] == 'C')
{
ans = nt.co;
return;
}
if(g[nt.x][nt.y] == '*')
{
nt.co += cost;
vis[nt.x][nt.y] = 1;
q.push(nt);
}
if(g[nt.x][nt.y] == 'P')
for(int i = 1; i <= cnt; ++i)
{
if(!vis[t[i][0]][t[i][1]])
{
vis[t[i][0]][t[i][1]] = 1;
q.push(node{t[i][0],t[i][1],nt.co});
}
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&cost);
for(int i = 0; i < n; ++i) scanf("%s",g[i]);
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < m; ++j)
{
if(g[i][j] == 'Y')
{
st.x = i;
st.y = j;
st.co = 0;
}
else if(g[i][j] == 'P')
{
t[++cnt][0] = i;
t[cnt][1] = j;
}
}
}
bfs(st);
if(ans == 0x3f3f3f3f) printf("screw you!");
else printf("%d",ans);
return 0;
}