Cod sursa(job #6406)

Utilizator devilkindSavin Tiberiu devilkind Data 19 ianuarie 2007 13:24:55
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.14 kb
#include <stdio.h>
#define NMAX 2024

FILE *f = fopen("barbar.in","rt"), *g = fopen("barbar.out","wt");

struct pozc{long int x,y,cost;};

long int n,m,i,j,k,a[NMAX][NMAX],cost[NMAX][NMAX],hash[NMAX][NMAX];
pozc heap[NMAX*NMAX*2];
long int cd[NMAX*NMAX*2][2],dr,dimh,start[2],fin[2],st,nr;
long int dist[NMAX][NMAX];


void citire()
{char D[2048];
fscanf(f,"%ld %ld",&n,&m);

for (i=0;i<=n+1;i++)
    {hash[i][m+1]=1;
    hash[i][0]=1;}

for (i=0;i<=m+1;i++)
    {hash[n+1][i]=1;
    hash[0][i]=1;}


char c;
c=fgetc(f);
for (i=1;i<=n;i++)
    {

    fgets(D,2024,f);
    for (j=1;j<=m;j++)
        {if (D[j-1]=='.') a[i][j]=0;
        if (D[j-1]=='*') {a[i][j]=1;nr++;}
	if (D[j-1]=='D') {cd[++dr][0]=i;cd[dr][1]=j;hash[i][j]=1;a[i][j]=0;}
	if (D[j-1]=='I') {start[0]=i;start[1]=j;a[i][j]=0;}
	if (D[j-1]=='O') {fin[0]=i;fin[1]=j;a[i][j]=0;}
        }
    }
}

int BF(long int c)
{long int i,final,x,y;
final=dr;
for (i=st;i<=dr;i++)
    {cost[cd[i][0]][cd[i][1]]=c;
    x=cd[i][0];y=cd[i][1];
    if (!hash[x-1][y]&&(!a[x-1][y])) {cd[++final][0]=x-1;cd[final][1]=y;hash[x-1][y]=1;}
    if (!hash[x][y-1]&&(!a[x][y-1])) {cd[++final][0]=x;cd[final][1]=y-1;hash[x][y-1]=1;}
    if (!hash[x+1][y]&&(!a[x+1][y])) {cd[++final][0]=x+1;cd[final][1]=y;hash[x+1][y]=1;}
    if (!hash[x][y+1]&&(!a[x][y+1])) {cd[++final][0]=x;cd[final][1]=y+1;hash[x][y+1]=1;}
    }
if (final==dr) return 0;
st=dr+1;
dr=final;
return 1;
}
    
void addheap(long int x, long int y, long int c)
{
dimh++;
heap[dimh].x=x;
heap[dimh].y=y;
heap[dimh].cost=c;
long int i;
i=dimh;
pozc aux;
while (heap[i].cost>heap[i/2].cost&&i>1)
    {aux=heap[i];
    heap[i]=heap[i/2];
    heap[i/2]=aux;
    i/=2;}
}

void recheap(long int poz)
{
long int i,max;
pozc aux;
i=poz;
max=i;
if (heap[max].cost<heap[i*2].cost&&i*2<=dimh) max=i*2;
if (heap[max].cost<heap[i*2+1].cost&&i*2+1<=dimh) max=i*2+1;
if (max!=i)
    {
    aux=heap[i];
    heap[i]=heap[max];
    heap[max]=aux;
    recheap(max);
    }
}   

void extract()
{
heap[1]=heap[dimh];
dimh--;
recheap(1);
}


long int MIN(long int a, long int b)
{
if (a>b) return b;
return a;
}
    
void djikstra()
{
long int i,x,y;

for (i=1;i<=n*m&&dimh;i++)
    {x=heap[1].x;y=heap[1].y;
    dist[x][y]=heap[1].cost;
    extract();
    if (!hash[x-1][y]&&(!a[x-1][y])) {addheap(x-1,y,MIN(dist[x][y],cost[x-1][y]));hash[x-1][y]=1;}
    if (!hash[x+1][y]&&(!a[x+1][y])) {addheap(x+1,y,MIN(dist[x][y],cost[x+1][y]));hash[x+1][y]=1;}
    if (!hash[x][y-1]&&(!a[x][y-1])) {addheap(x,y-1,MIN(dist[x][y],cost[x][y-1]));hash[x][y-1]=1;}
    if (!hash[x][y+1]&&(!a[x][y+1])) {addheap(x,y+1,MIN(dist[x][y],cost[x][y+1]));hash[x][y+1]=1;}
    }
}
    
    
    
    
    


void solve()
{long int ok;
ok=1;
st=1;
i=1;
while (ok)
    {ok=BF(i-1);
    i++;}


for (i=1;i<=n;i++)
    for (j=1;j<=m;j++)
        hash[i][j]=0;
dimh=1;
heap[1].x=start[0];
heap[1].y=start[1];
heap[1].cost=cost[start[0]][start[1]];
dist[fin[0]][fin[1]]=-1;
djikstra();

fprintf(g,"%ld",dist[fin[0]][fin[1]]);

}


int main()
{
citire();
solve();
fclose(f);
fclose(g);
return 0;
}