Pagini recente » Clasamentul arhivei de probleme | Cod sursa (job #2092965) | Clasamentul arhivei de probleme | Cod sursa (job #3298862)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
char v[1001][1001];
int dist[1001][1001];
bool aux[1001][1001];
int n,m;
int di[4]={-1,0,1,0};
int dj[4]={0,1,0,-1};
queue<pair<int,int>> Q;
bool in_mat(int i,int j)
{
return i>=1 && i<=n && j>=1 && j<=m;
}
void LEE()
{
while(!Q.empty())
{
int i=Q.front().first;
int j=Q.front().second;
Q.pop();
for(int k=0;k<4;k++)
{
int ni=i+di[k];
int nj=j+dj[k];
if(in_mat(ni,nj) && v[ni][nj]!='*' && v[ni][nj]!='D' && dist[ni][nj]==-1)
{
dist[ni][nj]=dist[i][j]+1;
Q.push({ni,nj});
}
}
}
}
struct node
{
int val,i,j;
};
node heap[1000001];
int sz=0;
void swap1(int node1,int node2)
{
swap(heap[node1],heap[node2]);
}
void urc(int node)
{
while(node>1 && heap[node/2].val<heap[node].val)
{
swap1(node,node/2);
node/=2;
}
}
void cobor(int node)
{
int fiu=2*node;
while(fiu<=sz)
{
if(fiu+1<=sz && heap[fiu+1].val>heap[fiu].val) fiu++;
if(heap[fiu].val>heap[node].val)
{
swap1(fiu,node);
node=fiu;
fiu=2*node;
}
else break;
}
}
void add(int val,int i,int j)
{
sz++;
heap[sz]={val,i,j};
urc(sz);
}
node top()
{
return heap[1];
}
void rem()
{
heap[1]=heap[sz--];
cobor(1);
}
void FILL(int xs,int ys,int xf,int yf)
{
add(dist[xs][ys],xs,ys);
aux[xs][ys]=true;
while(sz>0)
{
node cur=top();
rem();
int i=cur.i;
int j=cur.j;
int val=cur.val;
if(i==xf && j==yf)
{
fout<<val<<'\n';
return;
}
for(int k=0;k<4;k++)
{
int ni=i+di[k];
int nj=j+dj[k];
if(in_mat(ni,nj) && !aux[ni][nj] && v[ni][nj]!='*' && v[ni][nj]!='D')
{
aux[ni][nj]=true;
add(min(val,dist[ni][nj]),ni,nj);
}
}
}
fout<<-1<<'\n';
}
int main()
{
int xs,ys,xf,yf;
fin>>n>>m;
memset(dist,-1,sizeof(dist));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
fin>>v[i][j];
if(v[i][j]=='I')
{
xs=i;
ys=j;
}
else if(v[i][j]=='O')
{
xf=i;
yf=j;
}
else if(v[i][j]=='D')
{
dist[i][j]=0;
Q.push({i,j});
}
}
}
LEE();
if(dist[xf][yf]==-1 || dist[xs][ys]==-1)
{
fout<<-1<<'\n';
}
else
{
FILL(xs,ys,xf,yf);
}
return 0;
}