题目大意:给出一个地图,如果经过两个不同的区块,需要花费1,否则不需要花费。问从st到ed最小需要花费多少。
思路:签到题。
CODE:
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 510
#define MAXP 250010
#define MAXE 2000010
using namespace std;
const int dx[] = {0,1,-1,0,0};
const int dy[] = {0,0,0,1,-1};
struct Status{
int pos,len;
Status(int _,int __):pos(_),len(__) {}
bool operator <(const Status &a)const {
return len > a.len;
}
};
char src[MAX][MAX];
int num[MAX][MAX];
int head[MAXP],total;
int next[MAXE],aim[MAXE],length[MAXE];
int st,ed,m,n;
int f[MAXP];
inline void Initialize()
{
total = 0;
memset(head,0,sizeof(head));
}
inline void Add(int x,int y,int len)
{
next[++total] = head[x];
aim[total] = y;
length[total] = len;
head[x] = total;
}
inline int SPFA()
{
static priority_queue<Status> q;
while(!q.empty()) q.pop();
memset(f,0x3f,sizeof(f));
q.push(Status(st,0));
f[st] = 0;
while(!q.empty()) {
Status now = q.top(); q.pop();
if(f[now.pos] < now.len) continue;
int x = now.pos;
for(int i = head[x]; i; i = next[i])
if(f[aim[i]] > f[x] + length[i]) {
f[aim[i]] = f[x] + length[i];
q.push(Status(aim[i],f[aim[i]]));
}
}
return f[ed];
}
int main()
{
while(scanf("%d%d",&m,&n),m + n) {
Initialize();
for(int i = 1; i <= m; ++i)
scanf("%s",src[i] + 1);
int cnt = 0;
for(int i = 1; i <= m; ++i)
for(int j = 1; j <= n; ++j)
num[i][j] = ++cnt;
int x,y;
scanf("%d%d",&x,&y);
x++,y++,st = num[x][y];
scanf("%d%d",&x,&y);
x++,y++,ed = num[x][y];
for(int i = 1; i <= m; ++i)
for(int j = 1; j <= n; ++j)
for(int k = 1; k <= 4; ++k) {
int fx = i + dx[k];
int fy = j + dy[k];
if(!fx * fy || fx > m || fy > n) continue;
Add(num[i][j],num[fx][fy],src[fx][fy] != src[i][j]);
}
printf("%d\n",SPFA());
}
return 0;
}
CODE: