Cod sursa(job #484344)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 13 septembrie 2010 19:07:49
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.46 kb
#include<fstream>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

#define MAXN 1001
char mat[MAXN][MAXN];
int b[MAXN][MAXN];
int sol[MAXN][MAXN];
int n,m;

inline int min(const int a, const int b)
{
	return a<b?a:b;
}

int GetNeighbors(int x, int y, pair<int,int> v[4])
{
	int num=0;
	if(x-1>=1)
	{
		v[num++]=make_pair(x-1,y);
	}
	if(x+1<=n)
	{
		v[num++]=make_pair(x+1,y);
	}
	if(y-1>=1)
	{
		v[num++]=make_pair(x,y-1);
	}
	if(y+1<=m)
	{
		v[num++]=make_pair(x,y+1);
	}
	return num;
}

int BFS(const pair<int,int>& start, const pair<int,int>& end, const int minlen)
{
	queue<pair<int,int> > Q;
	Q.push(start);
	bool visited[MAXN][MAXN]={{false}};
	visited[start.first][start.second]=true;
	while(!Q.empty())
	{
		pair<int,int> v[4];
		const pair<int,int> node=Q.front();
		const int num=GetNeighbors(node.first,node.second,v);
		Q.pop();
		
		if(node.first==end.first && node.second==end.second)
			return 1;
		for(int i=0; i<num; ++i)
		{
			if(!visited[v[i].first][v[i].second] && b[v[i].first][v[i].second]>=minlen)
			{
				Q.push(v[i]);
				visited[v[i].first][v[i].second]=true;
			}
		}
	}
	return 0;
}

int main()
{
	fstream fin("barbar.in", fstream::in);
	fstream fout("barbar.out", fstream::out);
	queue<pair<int,int> > Q;
	pair<int,int> start,end;
	
	fin>>n>>m;
	//cout<<n<<" "<<m<<endl;
	for(int i=1; i<=n; ++i)
	{
		for(int j=1; j<=m; ++j)
		{
			fin>>mat[i][j];
			sol[i][j]=-1;
			switch(mat[i][j])
			{
				case 'D':
				{
					Q.push(make_pair(i,j));
					b[i][j]=0;
				}; break;
				case '*':
				{
					b[i][j]=-2;
				}; break;
				case 'I':
				{
					start=make_pair(i,j);
					b[i][j]=-1;
				}; break;
				case 'O':
				{
					end=make_pair(i,j);
					b[i][j]=-1;
				}; break;
				default:
					b[i][j]=-1;
			}
			//cout<<mat[i][j];
		}
		//cout<<endl;
	}
	fin.close();

	while(!Q.empty())
	{
		pair<int,int> node=Q.front(), v[4];
		int num=GetNeighbors(node.first,node.second,v);
		Q.pop();
		
		for(int i=0; i<num; ++i)
		{
			if( b[v[i].first][v[i].second]==-1 ||
				b[node.first][node.second]+1<b[v[i].first][v[i].second])
			{
				Q.push(v[i]);
				b[v[i].first][v[i].second]=b[node.first][node.second]+1;
			}
		}
	}
	
	/*cout<<endl;
	for(int i=1; i<=n; ++i)
	{
		for(int j=1; j<=m; ++j)
		{
			cout<<b[i][j]<<" ";
		}
		cout<<endl;
	}
	
	cout<<endl;*/
	
	int l=0,r=b[start.first][start.second];
	int minlen=0;
	bool accesible=false;
	while(l<r)
	{
		minlen=(l+r)>>1;
		if(BFS(start,end,minlen))
		{
			accesible=true;
			l=minlen+1;
		}
		else
		{
			r=minlen;
		}
	}
	
	if(accesible)
		fout<<minlen<<endl;
	else
		fout<<-1<<endl;
	
	/*Q.push(start);
	sol[start.first][start.second]=b[start.first][start.second];
	while(!Q.empty())
	{
		pair<int,int> node=Q.front(), v[4];
		int num=GetNeighbors(node.first,node.second,v);
		Q.pop();

		for(int i=0; i<num; ++i)
		{
			if(sol[v[i].first][v[i].second]==-1)
			{
				sol[v[i].first][v[i].second]=
					min(sol[node.first][node.second],b[v[i].first][v[i].second]);
				Q.push(v[i]);
			}
			else
			{
				int minimum=min(sol[node.first][node.second],b[v[i].first][v[i].second]);
				if(minimum>sol[v[i].first][v[i].second])
				{
					sol[v[i].first][v[i].second]=minimum;
					Q.push(v[i]);
				}
			}
		}
	}

	if(sol[end.first][end.second]<0)
		fout<<-1<<endl;
	else
		fout<<sol[end.first][end.second]<<endl;*/
	fout.close();
	return 0;
}