http://acm.hdu.edu.cn/showproblem.php?pid=4308
题意:
给出一个r*c的图以及走一步所需的花费
'Y'表示起始点 'C'表示重点
'*'表示可以达到的点 '#'表示不能达到的点
'P'表示可瞬间转换的点,及若从一个'P'点进入,可由下一个'P'点开始搜索
求到达'C'点的最小花费
('P'点间转化不需要花费)
代码:
#include<iostream>
#include<string>
#include<queue>
#include<cstdlib>
#include<cstdio>
#define MAX 5001
using namespace std;
struct P
{
int x,y;
}p[505];
struct node
{
int x,y,cost;
};
int dir[4][2]={1,0,-1,0,0,1,0,-1};
char map[MAX][MAX];
char vist[MAX][MAX];
int r,c,cost;
int s_x,s_y,e_x,e_y;
int k;
int BFS()
{
queue<node> q;
node now,next;
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
vist[i][j]=0;
now.x=s_x;
now.y=s_y;
now.cost=0;
q.push(now);
vist[s_x][s_y]=true;
while(!q.empty())
{
now=q.front();
q.pop();
if(now.x==e_x && now.y==e_y) return now.cost-cost;
for(int i=0;i<4;i++)
{
next.x=now.x+dir[i][0];
next.y=now.y+dir[i][1];
if(next.x<0 || next.x>=r || next.y<0 || next.y>=c) continue;
if(vist[next.x][next.y]) continue;
if(map[next.x][next.y]=='#') continue;
if(map[next.x][next.y]=='*')
{
next.cost=now.cost+cost;
q.push(next);
vist[next.x][next.y]=true;
}
else if(map[next.x][next.y]=='P')
{
if(vist[next.x][next.y]) continue;
for(int j=0;j<k;j++)
{
next.x=p[j].x;
next.y=p[j].y;
next.cost=now.cost;
q.push(next);
vist[next.x][next.y]=true;
}
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d%d",&r,&c,&cost)!=EOF)
{
k=0;
for(int i=0;i<r;i++)
{
cin>>map[i];
for(int j=0;j<c;j++)
{
if(map[i][j]=='Y')
{
s_x=i;
s_y=j;
}
else if(map[i][j]=='C')
{
e_x=i;
e_y=j;
map[i][j]='*';
}
else if(map[i][j]=='P')
{
p[k].x=i;
p[k].y=j;
k++;
}
}
}
int ans=BFS();
if(ans==-1) printf("Damn teoy!\n");
else printf("%d\n",ans);
}
return 0;
}
思路:
若遇到一个P点,将所有P点放入队列