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; }