Pagini recente » Cod sursa (job #832625) | Cod sursa (job #2194158) | Cod sursa (job #2350854) | Cod sursa (job #2198511) | Cod sursa (job #1221811)
#include<cstdio>
#include<algorithm>
#define GOL '.'
#define DRAGON 'D'
#define START 'I'
#define FINISH 'O'
#define WALL '*'
#define NM 1005
#define Q 1000003
#define INF 0x3f3f3f3f
using namespace std;
const int dx[4] = {-1, 0, 0, 1};
const int dy[4] = {0, -1, 1, 0};
char a[NM][NM];
bool viz[NM][NM];
int d[NM][NM],g[NM][NM];
int X1[Q],X2[Q],Y1[Q],Y2[Q],hp;
typedef struct tr{
int i,j,dist;
}TRIO;
TRIO h[NM];
void upheap(int k){
while(k>1 && h[k].dist > h[k/2].dist)
{
swap(h[k],h[k/2]);
k /= 2;
}
}
void downheap(int k){
int nod = 1;
while(nod)
{
nod = 0;
if(k + k <= hp)
{
nod = k + k;
if(nod < hp && h[nod+1].dist > h[nod].dist) nod++;
if(h[nod].dist <= h[k].dist) nod = 0;
if(nod)
{
swap(h[k],h[nod]);
k = nod;
}
}
}
}
int main(){
freopen("barbar.in","r",stdin);
freopen("barbar.out","w",stdout);
int N,M,k,kk,i,j,t;
int SX,SY,FX,FY,DX,DY;
SX=SY=FX=FY=0;
scanf("%d%d\n",&N,&M);
for(i=1;i<=N;++i) scanf("%s",a[i]+1);
k = 0;
int *x1, *x2, *y1, *y2;
x1 = X1; x2 = X2;
y1 = Y1; y2 = Y2;
for(i=1;i<=N;++i)
for(j=1;j<=M;++j)
{
if(a[i][j] == DRAGON)
{
++k;
x1[k] = i;
y1[k] = j;
}
if(a[i][j] == START)
{
SX = i;
SY = j;
}
if(a[i][j] == FINISH)
{
FX = i;
FY = j;
}
d[i][j] = INF;
}
for(i=1;i<=k;++i) d[x1[i]][y1[i]] = 0;
while(k>0)
{
kk = 0;
for(i=1;i<=k;++i)
{
for(t=0;t<4;++t)
{
DX = x1[i] + dx[t]; DY = y1[i] + dy[t];
if(a[DX][DY] == WALL || DX > N || DY > M || DX<1 || DY<1) continue;
if(d[DX][DY] <= d[x1[i]][y1[i]] + 1) continue;
d[DX][DY] = d[x1[i]][y1[i]] + 1;
x2[++kk] = DX;
y2[kk] = DY;
}
}
k = kk;
swap(x1,x2);
swap(y1,y2);
}
hp = 1;
h[1].i = SX; h[1].j = SY; h[1].dist = d[SX][SY];
viz[SX][SY] = 1; g[SX][SY] = d[SX][SY];
int x,y,dst;
while(hp>0)
{
x = h[1].i; y = h[1].j; dst = h[1].dist;
if(hp>1)
{
swap(h[1],h[hp]);
-- hp;
downheap(1);
}
else --hp;
for(t=0;t<4;++t)
{
DX = x + dx[t]; DY = y + dy[t];
if(viz[DX][DY] || DX<1 || DY<1 || DX > N || DY > M || a[DX][DY] == WALL) continue;
viz[DX][DY] = 1;
g[DX][DY] = min(dst, d[DX][DY]);
++hp;
h[hp].i = DX;
h[hp].j = DY;
h[hp].dist = g[DX][DY];
upheap(hp);
}
}
if(!viz[FX][FY]) printf("-1\n");
else printf("%d\n",g[FX][FY]);
return 0;
}