Cod sursa(job #1033568)

Utilizator AnonymouslegionAnonymous Anonymouslegion Data 17 noiembrie 2013 11:05:40
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

int n, m, source, dest, dx[4] = {-1005, 0, 1005, 0}, dy[4] = {0, 1, 0, -1}, vis[1200005], dist[1200005], dad[1200005];
string mat[1005];
queue<int> q;
vector<int> pts[2005];

int valid(int p){
  int x = p / 1005, y = p % 1005 - 1;
  if(x >= 0 && x < n && y >= 0 && y < m)
    if(!vis[p] && mat[x][y] != '*')
      return 1;
  return 0;
}

void bfs(){
  while(!q.empty()){
    int now = q.front();
    q.pop();
    pts[dist[now]].push_back(now);
    for(int i = 0; i < 4; ++i){
      int nex = now + dx[i] + dy[i];
      if(valid(nex)){
        vis[nex] = 1;
        q.push(nex);
        dist[nex] = dist[now] + 1;
      }
    }
  }
}

inline int convert(int x, int y){
  return x * 1005 + y + 1;
}

int rad(int x){
  if(dad[x] == x)
    return x;
  dad[x] = rad(dad[x]);
  return dad[x];
}

void unite(int x, int y){
  dad[rad(x)] = rad(y);
}

void neib(int p){
  vis[p] = 0;
  for(int i = 0; i < 4; ++i){
    int ne = p + dx[i] + dy[i];
    if(valid(ne))
      unite(p, ne);
  }
}

int main(){
  ifstream in("barbar.in");
  ofstream out("barbar.out");

  in >> n >> m;

  for(int i = 0; i < n; ++i)
    in >> mat[i];

  for(int i = 0; i < n; ++i)
    for(int j = 0; j < mat[i].size(); ++j)
      if(mat[i][j] == 'D'){
        q.push(convert(i, j));
        vis[convert(i, j)] = 1;
      }
      else if(mat[i][j] == 'O')
        dest = convert(i, j);
      else if(mat[i][j] == 'I')
        source = convert(i, j);

  bfs();

  for(int i = 0 ; i <= 1200000; ++i)
    dad[i] = i;

  for(int i = 2000; i > 0; --i){
    for(int j = 0; j < pts[i].size(); ++j)
      neib(pts[i][j]);
    if(rad(source) == rad(dest)){
      out << i;
      return 0;
    }
  }

  out << "-1";
  return 0;
}