fbpx

Problema #869 – Acces2 – Rezolvari PBInfo

de Mihai-Alexandru

Cerința

Se consideră o clădire de formă dreptunghiulară, împărțită în n*m camere, dispuse sub forma unei matrice cu n linii și m coloane. Dintr-o cameră se poate trece în oricare dintre cele 4 camere vecine pe linie sau pe coloană. Unele camere sunt închise, și în ele nu se poate intra deloc. Trecerea dintr-o cameră în altă cameră durează un minut.

Camerele formează zone. O zonă este alcătuită dintr-un număr maxim de camere cu proprietatea că oricum am alege două camere din zonă se poate ajunge dintr-o cameră în alta trecând doar prin camere libere.

În anumite camere se află echipe de pompieri. Fiecare echipă deservește zona din care face parte camera echipei.

S-a constatat că așezarea echipelor în camere nu este tocmai corectă. Mai precis, există zone care nu sunt deservite de nicio echipă de pompieri. Pentru corectarea acestei probleme există două operații posibile:

  • mutarea unor echipe din camera curentă în altă cameră – operație care costă 1 leu
  • crearea unor echipe noi și plasare lor în camere – operație care costă 2 lei

Să se determine costul total minim al operațiilor necesare, astfel încât fiecare zonă din clădire să fie deservită de cel puțin o echipă de pompieri.

Date de intrare

Fișierul de intrare acces2.in conține pe prima linie numerele n m; următoarele n linii conțin câte m caractere, care pot fi:

  • - – reprezintă o cameră liberă
  • # – reprezintă o cameră închisă
  • P – reprezintă o cameră în care se găsește o echipă de pompieri

Date de ieșire

Fișierul de ieșire acces2.out va conține pe prima linie costul total minim.

Restricții și precizări

  • 1 ≤ n,m ≤ 1000

Exemplu

acces2.in

4 6
P-#-#P
--###-
##P-P#
--#--#

acces2.out

3

Explicație

În clădire sunt 5 zone: una este deservită de 2 echipe, două sunt deservite de câte o echipă și două nu sunt deservite deloc. Costul minim 3 se obține prin mutarea unei echipe (cost 1) și crearea unei echipe noi (cost 2).

#include <bits/stdc++.h>

using namespace std;

ifstream cin("acces2.in");
ofstream cout("acces2.out");

int n , m , a[1001][1001] , cnt , nrp , nrc , sum , pazi , pomp , ind;
char s;

const int di[] = { 0 , 0 , -1 , 1};
const int dj[] = {-1 , 1 ,  0 , 0};

struct poz
{
    int i , j;
};

int inside(int i , int j)
{
    return i >= 1 && i <= n && j >= 1 && j <= m;
}

poz c[1001];

queue <poz> q;

void lee(int i , int j)
{
    poz r;
    r.i = i , r.j = j;
    a[r.i][r.j] = ind;
    q.push(r);
    while(!q.empty())
    {
        poz r;
        r = q.front();
        for(int i = 0 ; i < 4 ; i++)
        {
            int inou = r.i + di[i];
            int jnou = r.j + dj[i];
            if(a[inou][jnou] == -2) nrp++;
            if(inside(inou , jnou) && (a[inou][jnou] == 0 || a[inou][jnou] == -2))
            {
                a[inou][jnou] = ind;
                q.push({inou , jnou});
            }
        }
        q.pop();
    }
}
int main()
{
    cin >> n >> m;
    for(int i = 1 ; i <= n ; i++)
        for(int j = 1 ; j <= m ; j++)
    {
        cin >> s;
        if(s == '#') a[i][j] = -1;
        else if(s == '_') a[i][j] = 0;
        else if(s == 'P') a[i][j] = -2;
    }
    for(int i = 1 ; i <= n ; i++)
        for(int j = 1 ; j <= m ; j++)
            if(a[i][j] == 0)
            {
                ind++;
                nrp = 0;
                lee(i , j);
                if(nrp > 0) pomp += (nrp - 1);
                else nrc++;
            }
    if(pomp >= nrc) sum = pomp - nrc;
    else sum += (2 * (nrc - pomp)) + pomp;
    cout << sum;
}
Comentarii

S-ar putea sa iti placa