题意:http://acm.hdu.edu.cn/showproblem.php?pid=4308
从Y到C,遇#不能走,遇*花钱,全部的P连通,问最少花费。
解:
简单宽搜。第一次遇到p就将所有的连通的p都放进队列。
View Code
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct point{
int x, y;
int sum;
};
bool flag[5000 + 10][5000 + 10];
int r, c, cost;
char map[5000 + 10][5000 + 10];
int dir[4][2] = {
, 0,
-1, 0,
, 1,
, -1
};
int count_;
int xx[5000 + 10];
int yy[5000 + 10];
int bfs(point start, point end){
queue < point > q;
q.push(start);
int ans = -1;
int flag1 = 0;
while(!q.empty()){
point tmp = q.front();
q.pop();
for(int i = 0; i < 4; i ++){
int x = tmp.x + dir[i][0];
int y = tmp.y + dir[i][1];
if(x < 0 || x >= r || y < 0 || y >= c){
continue;
}
if(x == end.x && y == end.y){
//return tmp.sum;
if(tmp.sum < ans || ans == -1)
ans = tmp.sum;
continue;
}
if(map[x][y] == '#')
continue;
if(flag[x][y] == 1)
continue;
point now;
now.x = x;
now.y = y;
now.sum = tmp.sum;
if(map[x][y] == '*'){
flag[x][y] = 1;
now.sum = tmp.sum + cost;
q.push(now);
}
if(map[x][y] == 'P'){/*
if(y + 2 < c && map[x][y + 2] == 'P'){
flag[x][y + 2] = 1;
now.y = y + 2;
q.push(now);
}
if(y - 2 >= 0 && map[x][y - 2] == 'P'){
flag[x][y - 2] = 1;
now.y = y - 2;
q.push(now);
}
if(x + 2 < r && map[x + 2][y] == 'P'){
flag[x + 2][y] = 1;
now.x = x + 2;
q.push(now);
}
if(x - 2 >= 0 && map[x - 2][y] == 'P'){
flag[x - 2][y] = 1;
now.x = x - 2;
q.push(now);
}*/
if(flag1 == 1) continue;
flag1 = 1;
for(int j = 0; j < count_; j ++){
now.x = xx[j];
now.y = yy[j];
flag[now.x][now.y] = 1;
q.push(now);
}
}
}
}
//return -1;
return ans;
}
int main(){
while(~scanf("%d%d%d", &r, &c, &cost)){
for(int i = 0; i < r; i ++){
scanf("%s", map[i]);
}
point start, end;
memset(flag, 0, sizeof(flag));
count_ = 0;
for(int i = 0; i < r; i ++){
for(int j = 0; j < c; j ++){
if(map[i][j] == 'Y'){
start.x = i;
start.y = j;
flag[i][j] = 1;
}
if(map[i][j] == 'C'){
end.x = i;
end.y = j;
}
if(map[i][j] == 'P'){
xx[count_] = i;
yy[count_ ++] = j;
}
}
}
start.sum = 0;
int f = bfs(start, end);
if(f == -1)
puts("Damn teoy!");
else
printf("%d\n", f);
}
return 0;
}