|
| 1 | +#include <iostream> |
| 2 | +#include <sstream> |
| 3 | +#include <vector> |
| 4 | +#include <algorithm> |
| 5 | +#include <set> |
| 6 | +#include <map> |
| 7 | +#include <cstring> |
| 8 | +#include <queue> |
| 9 | +using namespace std; |
| 10 | +int FC[105][105], FP[105][105]; |
| 11 | +int D[105][105]; |
| 12 | +int C[105][2], P[105][2]; |
| 13 | +int n, m; |
| 14 | +int cx, px; |
| 15 | +typedef pair<int, int> pi; |
| 16 | +#define valid(x, y) ( (x) >= 0 && (x) <= n && (y) >= 0 && (y) <= (m) ? 1 : 0 ) |
| 17 | + |
| 18 | +class Parking { |
| 19 | + public: |
| 20 | + void bfs(int sx, int sy, char M[105][105]){ |
| 21 | + int L[105][105]; |
| 22 | + memset(L, -1, sizeof(L)); |
| 23 | + L[sx][sy] = 0; |
| 24 | + pi s = make_pair(sx, sy); |
| 25 | + queue<pi> Q; |
| 26 | + Q.push(s); |
| 27 | + while(!Q.empty()){ |
| 28 | + pi v = Q.front(); |
| 29 | + Q.pop(); |
| 30 | + int vx = v.first, vy = v.second; |
| 31 | +// cout<<vx<<" "<<vy<<endl; |
| 32 | + int l = L[vx][vy]; |
| 33 | + |
| 34 | + if(valid(vx, vy) && M[vx][vy] != 'X'){ |
| 35 | + if(valid(vx+1, vy) && L[vx+1][vy] < 0){ |
| 36 | + L[vx+1][vy] = l+1; |
| 37 | + Q.push(make_pair(vx+1, vy)); |
| 38 | + } |
| 39 | + if(valid(vx-1, vy) && L[vx-1][vy] < 0){ |
| 40 | + L[vx-1][vy] = l+1; |
| 41 | + Q.push(make_pair(vx-1, vy)); |
| 42 | + } |
| 43 | + if(valid(vx, vy+1) && L[vx][vy+1] < 0){ |
| 44 | + L[vx][vy+1] = l+1; |
| 45 | + Q.push(make_pair(vx, vy+1)); |
| 46 | + } |
| 47 | + if(valid(vx, vy-1) && L[vx][vy-1] < 0){ |
| 48 | + L[vx][vy-1] = l+1; |
| 49 | + Q.push(make_pair(vx, vy-1)); |
| 50 | + } |
| 51 | + if(M[vx][vy] == 'P') |
| 52 | + D[FC[sx][sy]][FP[vx][vy]] = l; |
| 53 | + } |
| 54 | + } |
| 55 | + } |
| 56 | + int minTime(vector <string> S) |
| 57 | + { |
| 58 | + n = S.size(), m = S[0].size(); |
| 59 | + char M[105][105]; |
| 60 | + for(int i = 0; i <= n; i++) |
| 61 | + for(int j = 0; j <= m; j++) |
| 62 | + if(!i || !j) M[i][j] = 'X'; |
| 63 | + else M[i][j] = S[i-1][j-1]; |
| 64 | + memset(FC, -1, sizeof(FC)); |
| 65 | + memset(FP, -1, sizeof(FP)); |
| 66 | + memset(D, -1, sizeof(D)); |
| 67 | + memset(C, -1, sizeof(C)); |
| 68 | + memset(P, -1, sizeof(P)); |
| 69 | + |
| 70 | + cx = 0; px = 0; |
| 71 | + for(int i = 1; i <= n; i++) |
| 72 | + for(int j = 1; j <= m; j++){ |
| 73 | + if(M[i][j] == 'C'){ |
| 74 | + C[cx][0] = i; |
| 75 | + C[cx][1] = j; |
| 76 | + FC[i][j] = cx++; |
| 77 | + } |
| 78 | + else if(M[i][j] == 'P'){ |
| 79 | + P[px][0] = i; |
| 80 | + P[px][1] = j; |
| 81 | + FP[i][j] = px++; |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + cout<<"cx = "<<cx<<" px = "<<px<<endl; |
| 86 | + if(!cx) return 0; |
| 87 | + if(px < cx) return -1; |
| 88 | + |
| 89 | + for(int i = 0; i < cx; i++) |
| 90 | + bfs(C[i][0], C[i][1], M); |
| 91 | +/* |
| 92 | + for(int i = 0; i < cx; i++){ |
| 93 | + for(int j = 0; j < px; j++) |
| 94 | + cout<<D[i][j]<<" "; |
| 95 | + cout<<endl; |
| 96 | + } |
| 97 | +*/ |
| 98 | + set<int> E; |
| 99 | + for(int i = 0; i < cx; i++) |
| 100 | + for(int j = 0; j < px; j++) |
| 101 | + if(D[i][j] > 0) |
| 102 | + E.insert(D[i][j]); |
| 103 | + |
| 104 | + for(set<int>::iterator it = E.begin(); it != E.end(); it++){ |
| 105 | + int e = *it; |
| 106 | + cout<<"e = "<<e<<endl; |
| 107 | + int G[105][105]; |
| 108 | + int R[105][105]; |
| 109 | + memset(G, 0, sizeof(G)); |
| 110 | + memset(R, 0, sizeof(R)); |
| 111 | + for(int i = 0; i < cx; i++) |
| 112 | + for(int j = 0; j < px; j++) |
| 113 | + if(D[i][j] <= e && D[i][j] != -1) |
| 114 | + G[i][j] = 1; |
| 115 | + int MA[105], MB[105], seen[105]; |
| 116 | + memset(MA, -1, sizeof(MA)); |
| 117 | + memset(MB, -1, sizeof(MB)); |
| 118 | + int max_flow = 0; |
| 119 | + for(int i = 0; i < cx; i++){ |
| 120 | + memset(seen, 0, sizeof(seen)); |
| 121 | + if(findMatch(G, i, MA, MB, seen)) max_flow++; |
| 122 | + } |
| 123 | + |
| 124 | + if(max_flow == cx) return e; |
| 125 | + cout<<max_flow<<endl; |
| 126 | + } |
| 127 | + return -1; |
| 128 | + } |
| 129 | + |
| 130 | + bool findMatch(int G[105][105], int i, int MA[105], int MB[105], int seen[105]){ |
| 131 | + |
| 132 | + for(int j = 0; j < px; j++){ |
| 133 | + if(G[i][j] && !seen[j]){ |
| 134 | + seen[j] = 1; |
| 135 | + if(MB[j] == -1 || findMatch(G, MB[j], MA, MB, seen)){ |
| 136 | + MB[j] = i; |
| 137 | + MA[i] = j; |
| 138 | + return true; |
| 139 | + } |
| 140 | + } |
| 141 | + } |
| 142 | + return false; |
| 143 | + } |
| 144 | + |
| 145 | + |
| 146 | +// BEGIN CUT HERE |
| 147 | + public: |
| 148 | + void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); } |
| 149 | + private: |
| 150 | + template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } |
| 151 | + void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PDSSED" << endl; else { cerr << "FDILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } |
| 152 | + void test_case_0() { string Drr0[] = {"C.....P", |
| 153 | + "C.....P", |
| 154 | + "C.....P"}; vector <string> Drg0(Drr0, Drr0 + (sizeof(Drr0) / sizeof(Drr0[0]))); int Drg1 = 6; verify_case(0, Drg1, minTime(Drg0)); } |
| 155 | + void test_case_1() { string Drr0[] = {"C.X.....", |
| 156 | + "..X..X..", |
| 157 | + "..X..X..", |
| 158 | + ".....X.P"}; vector <string> Drg0(Drr0, Drr0 + (sizeof(Drr0) / sizeof(Drr0[0]))); int Drg1 = 16; verify_case(1, Drg1, minTime(Drg0)); } |
| 159 | + void test_case_2() { string Drr0[] = {"XXXXXXXXXXX", |
| 160 | + "X......XPPX", |
| 161 | + "XC...P.XPPX", |
| 162 | + "X......X..X", |
| 163 | + "X....C....X", |
| 164 | + "XXXXXXXXXXX"} |
| 165 | +; vector <string> Drg0(Drr0, Drr0 + (sizeof(Drr0) / sizeof(Drr0[0]))); int Drg1 = 5; verify_case(2, Drg1, minTime(Drg0)); } |
| 166 | + void test_case_3() { string Drr0[] = {".C.", |
| 167 | + "...", |
| 168 | + "C.C", |
| 169 | + "X.X", |
| 170 | + "PPP"}; vector <string> Drg0(Drr0, Drr0 + (sizeof(Drr0) / sizeof(Drr0[0]))); int Drg1 = 4; verify_case(3, Drg1, minTime(Drg0)); } |
| 171 | + void test_case_4() { string Drr0[] = {"PPPPPPPPPPCCCCCCCCCC", |
| 172 | +"PPPPPPPPPPCCCCCCCCCC", "PPPPPPPPPPCCCCCCCCCC", "PPPPPPPPPPCCCCCCCCCC", "PPPPPPPPPPCCCCCCCCCC", "PPPPPPPPPPCCCCCCCCCC", "PPPPPPPPPPCCCCCCCCCC", "PPPPPPPPPPCCCCCCCCCC", "PPPPPPPPPPCCCCCCCCCC", |
| 173 | +"PPPPPPPPPPCCCCCCCCCC" }; vector <string> Drg0(Drr0, Drr0 + (sizeof(Drr0) / sizeof(Drr0[0]))); int Drg1 = 10; verify_case(4, Drg1, minTime(Drg0)); } |
| 174 | + void test_case_5() { string Drr0[] = {"..X..", |
| 175 | + "C.X.P", |
| 176 | + "..X.."}; vector <string> Drg0(Drr0, Drr0 + (sizeof(Drr0) / sizeof(Drr0[0]))); int Drg1 = -1; verify_case(5, Drg1, minTime(Drg0)); } |
| 177 | + |
| 178 | +// END CUT HERE |
| 179 | + |
| 180 | +}; |
| 181 | + |
| 182 | +// BEGIN CUT HERE |
| 183 | + int main() |
| 184 | + { |
| 185 | + Parking ___test; |
| 186 | + ___test.run_test(-1); |
| 187 | + } |
| 188 | +// END CUT HERE |
0 commit comments