Cod sursa(job #1016476)

Utilizator teoionescuIonescu Teodor teoionescu Data 26 octombrie 2013 12:51:10
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include<fstream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
ifstream in("barbar.in");
ofstream out("barbar.out");
const int nmax = 1005;
const int dlin[]={0,0,1,-1};
const int dcol[]={1,-1,0,0};
const int INF = 1<<30;
struct heap_item{
    int val,x,y;
};
struct MaxHeap{
    heap_item H[nmax*nmax];
    int K;
    void upheap(int i){
        if(i/2>=1 && H[i/2].val<H[i].val){
            swap(H[i/2],H[i]);
            upheap(i/2);
        }
    }
    void downheap(int i){
        if(2*i+1<=K && H[2*i+1].val>H[i].val && H[2*i+1].val>=H[2*i].val){
            swap(H[2*i+1],H[i]);
            downheap(2*i+1);
        }
        else if(2*i<=K && H[2*i].val>H[i].val){
            swap(H[2*i],H[i]);
            downheap(2*i);
        }
    }
    bool empty(){
        return K==0;
    }
    heap_item first(){
        return H[1];
    }
    void push(heap_item z){
        H[++K]=z;
        upheap(K);
    }
    void pop(){
        swap(H[1],H[K]);
        K--;
        downheap(1);
    }
};
struct point{
    int x,y;
} s,f;
int a[nmax][nmax];
int d[nmax][nmax];
int N,M;
queue<point> q;
MaxHeap H;
int main(){
    in>>N>>M;
    memset(a,-1,sizeof(a));
    for(int i=1;i<=N;i++){
        for(int j=1;j<=M;j++){
            char c;
            in>>c;
            if(c=='I'){s.x=i;s.y=j;d[i][j]=-1;}
            if(c=='O'){f.x=i;f.y=j;d[i][j]=-1;}
            if(c=='D'){point u;u.x=i;u.y=j;q.push(u);}
            if(c=='*'){a[i][j]=-2;}
            if(c=='.'){d[i][j]=-1;}
        }
    }
    for(int i=0;i<=N+1;i++){
        a[i][0]=-2;
        a[i][M+1]=-2;
    }
    for(int j=0;j<=M+1;j++){
        a[0][j]=-2;
        a[N+1][j]=-2;
    }
    while(!q.empty()){
        point u=q.front();
        q.pop();
        for(int k=0;k<=3;k++){
            int xx=u.x+dlin[k];
            int yy=u.y+dcol[k];
            if( a[xx][yy]!=-2 && ((d[xx][yy]==-1)||(d[u.x][u.y]+1<d[xx][yy])) ){
                d[xx][yy]=d[u.x][u.y]+1;
                point p;
                p.x=xx;
                p.y=yy;
                q.push(p);
            }
        }
    }
    heap_item start;
    start.val=d[s.x][s.y];
    start.x=s.x;
    start.y=s.y;
    H.push(start);
    while(!H.empty()){
        heap_item u=H.first();
        H.pop();
        if(u.val>a[u.x][u.y]){
            a[u.x][u.y]=u.val;
            for(int k=0;k<=3;k++){
                int xx=u.x+dlin[k];
                int yy=u.y+dcol[k];
                if( a[xx][yy]!=-2 && (a[xx][yy]==-1) ){
                    heap_item p;
                    p.val=min(u.val,d[xx][yy]);
                    p.x=xx;
                    p.y=yy;
                    H.push(p);
                }
            }
        }
    }
    out<<a[f.x][f.y];
    return 0;
}