Pagini recente » Cod sursa (job #2767515) | Cod sursa (job #418809) | Cod sursa (job #1381564) | Cod sursa (job #3139875) | Cod sursa (job #3242553)
#include <fstream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");
int const INF = 1e9+7;
struct Point {
int x;
int y;
};
Point start, stop;
int dirX[4] = {-1, 0, 1, 0};
int dirY[4] = {0, -1, 0, 1};
int const NMAX = 1000;
char mat[1 + NMAX][1 + NMAX];
int dist[1 + NMAX][1 + NMAX];
int active[1 + NMAX][1 + NMAX];
Point root[1 + NMAX][1 + NMAX];
int treeSize[1 + NMAX][1 + NMAX];
vector <Point> dungeon;
vector <Point> dragon;
bool isEqual(Point a, Point b) {
return (a.x == b.x && a.y == b.y);
}
Point findRoot(Point node) {
if(isEqual(node, root[node.x][node.y])) {
return node;
}
root[node.x][node.y] = findRoot(root[node.x][node.y]);
return root[node.x][node.y];
}
void connectNodes(Point a, Point b) {
Point rootA = findRoot(a), rootB = findRoot(b);
if(isEqual(rootA, rootB)) {
return;
}else {
if(treeSize[rootA.x][rootA.y] < treeSize[rootB.x][rootB.y]) {
root[rootA.x][rootA.y] = rootB;
treeSize[rootB.x][rootB.y] += treeSize[rootA.x][rootA.y];
}else {
root[rootB.x][rootB.y] = rootA;
treeSize[rootA.x][rootA.y] += treeSize[rootB.x][rootB.y];
}
}
}
bool compareDungeon(Point a, Point b) {
return (dist[a.x][a.y] > dist[b.x][b.y]);
}
void BFS(int n, int m) {
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
dist[i][j] = INF;
}
}
queue <Point> q;
for(int i = 0;i < dragon.size();i++) {
Point temp = dragon[i];
dist[temp.x][temp.y] = 0;
q.push(temp);
}
while(!q.empty()) {
Point from = q.front();
q.pop();
for(int dir = 0;dir < 4;dir++) {
Point to = {from.x + dirX[dir], from.y + dirY[dir]};
if(dist[to.x][to.y] == INF && mat[to.x][to.y] != '*') {
dist[to.x][to.y] = dist[from.x][from.y] + 1;
q.push(to);
}
}
}
}
int main() {
int n, m;
in >> n >> m;
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
in >> mat[i][j];
if(mat[i][j] == 'O') {
stop = {i, j};
}else if(mat[i][j] == 'I') {
start = {i, j};
}else if(mat[i][j] == 'D') {
dragon.push_back({i, j});
}
if(mat[i][j] != '*') {
dungeon.push_back({i, j});
}
root[i][j] = {i, j};
}
}
BFS(n, m);
/*for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
if(dist[i][j] == INF) {
cout << "# ";
}else {
cout << dist[i][j] << ' ';
}
}
cout << '\n';
}*/
sort(dungeon.begin(), dungeon.end(), compareDungeon);
for(int i = 0;i < dungeon.size();i++) {
Point from = dungeon[i];
active[from.x][from.y] = true;
for(int dir = 0;dir < 4;dir++) {
Point to = {from.x + dirX[dir], from.y + dirY[dir]};
if(active[to.x][to.y]) {
connectNodes(from, to);
}
}
if(isEqual(findRoot(start), findRoot(stop))) {
out << dist[from.x][from.y] << '\n';
return 0;
}
}
out << -1;
return 0;
}