/****************************************************************************** Online C++ Compiler. Code, Compile, Run and Debug C++ program online. Write your code in this editor and press "Run" button to compile and execute it. *******************************************************************************/ #include <iostream> using namespace std; const int MAXINT = 2147483647; const long long int MAXLINT = 9223372036854775807; int main() { int n, m, k; cin >> n >> m >> k; char c; bool sasiedzi[m][n]; for(int i=0; i < n; i++){ for(int j=0; j < m; j++){ cin >> c; if(c == '.') sasiedzi[j][i] = true; else sasiedzi[j][i] = false; } } int a, b; int x, y; long long int suma_tot = MAXLINT; int najlepsi = 0; long long int *d; int *p, *S; bool *QS; int sptr, v, u, l; for(int i=0; i < k; i++){ cin >> a >> b; d = new long long int[n*m]; // Tablica kosztów dojścia p = new int[n*m]; // Tablica poprzedników QS = new bool [n*m]; // Zbiory Q i S S = new int [n*m]; // Stos sptr = 0; // Wskaźnik stosu for(int j = 0; j < n*m; j++){ d[j] = MAXLINT; p[j] = -1; QS[j] = false; } v = 0; d[v] = 0; for(int j = 0; j < n*m; j++){ // Szukamy wierzchołka w Q o najmniejszym koszcie d for(l = 0; QS[l]; l++); for(u = l++; l < n*m; l++) if(!QS[l] && (d[l] < d[u])) u = l; // Znaleziony wierzchołek przenosimy do S QS[u] = true; // Modyfikujemy odpowiednio wszystkich sąsiadów u, którzy są w Q x = u%m; y = u/m; if(x < m-1 && sasiedzi[x+1][y] && !QS[m*y+x+1] && d[m*y+x+1] > d[u] + a){ d[m*y+x+1] = d[u] + a; p[m*y+x+1] = u; } if(x > 0 && sasiedzi[x-1][y] && !QS[m*y+x-1] && d[m*y+x-1] > d[u] + b){ d[m*y+x-1] = d[u] + b; p[m*y+x-1] = u; } if(y < n-1 && sasiedzi[x][y+1] && !QS[m*(y+1)+x] && d[m*(y+1)+x] > d[u] + a){ d[m*(y+1)+x] = d[u] + a; p[m*(y+1)+x] = u; } if(y > 0 && sasiedzi[x][y-1] && !QS[m*(y-1)+x] && d[m*(y-1)+x] > d[u] + b){ d[m*(y-1)+x] = d[u] + b; p[m*(y-1)+x] = u; } } // Ścieżkę przechodzimy od końca ku początkowi, // Zapisując na stosie kolejne wierzchołki for(l = n*m-1; l > -1; l = p[l]) S[sptr++] = l; // Wyświetlamy ścieżkę, pobierając wierzchołki ze stosu int poprz, nast; long long int suma; poprz = S[--sptr]; suma = 0; while(sptr){ nast = S[--sptr]; if(nast%m == poprz%m + 1 || nast/m == poprz/m + 1) suma += a; if(nast%m == poprz%m - 1 || nast/m == poprz/m - 1) suma += b; poprz = nast; } if(suma_tot > suma){ suma_tot = suma; najlepsi = 1; } else if(suma_tot == suma) najlepsi++; delete [ ] d; delete [ ] p; delete [ ] QS; delete [ ] S; } cout << suma_tot << ' ' << najlepsi; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | /****************************************************************************** Online C++ Compiler. Code, Compile, Run and Debug C++ program online. Write your code in this editor and press "Run" button to compile and execute it. *******************************************************************************/ #include <iostream> using namespace std; const int MAXINT = 2147483647; const long long int MAXLINT = 9223372036854775807; int main() { int n, m, k; cin >> n >> m >> k; char c; bool sasiedzi[m][n]; for(int i=0; i < n; i++){ for(int j=0; j < m; j++){ cin >> c; if(c == '.') sasiedzi[j][i] = true; else sasiedzi[j][i] = false; } } int a, b; int x, y; long long int suma_tot = MAXLINT; int najlepsi = 0; long long int *d; int *p, *S; bool *QS; int sptr, v, u, l; for(int i=0; i < k; i++){ cin >> a >> b; d = new long long int[n*m]; // Tablica kosztów dojścia p = new int[n*m]; // Tablica poprzedników QS = new bool [n*m]; // Zbiory Q i S S = new int [n*m]; // Stos sptr = 0; // Wskaźnik stosu for(int j = 0; j < n*m; j++){ d[j] = MAXLINT; p[j] = -1; QS[j] = false; } v = 0; d[v] = 0; for(int j = 0; j < n*m; j++){ // Szukamy wierzchołka w Q o najmniejszym koszcie d for(l = 0; QS[l]; l++); for(u = l++; l < n*m; l++) if(!QS[l] && (d[l] < d[u])) u = l; // Znaleziony wierzchołek przenosimy do S QS[u] = true; // Modyfikujemy odpowiednio wszystkich sąsiadów u, którzy są w Q x = u%m; y = u/m; if(x < m-1 && sasiedzi[x+1][y] && !QS[m*y+x+1] && d[m*y+x+1] > d[u] + a){ d[m*y+x+1] = d[u] + a; p[m*y+x+1] = u; } if(x > 0 && sasiedzi[x-1][y] && !QS[m*y+x-1] && d[m*y+x-1] > d[u] + b){ d[m*y+x-1] = d[u] + b; p[m*y+x-1] = u; } if(y < n-1 && sasiedzi[x][y+1] && !QS[m*(y+1)+x] && d[m*(y+1)+x] > d[u] + a){ d[m*(y+1)+x] = d[u] + a; p[m*(y+1)+x] = u; } if(y > 0 && sasiedzi[x][y-1] && !QS[m*(y-1)+x] && d[m*(y-1)+x] > d[u] + b){ d[m*(y-1)+x] = d[u] + b; p[m*(y-1)+x] = u; } } // Ścieżkę przechodzimy od końca ku początkowi, // Zapisując na stosie kolejne wierzchołki for(l = n*m-1; l > -1; l = p[l]) S[sptr++] = l; // Wyświetlamy ścieżkę, pobierając wierzchołki ze stosu int poprz, nast; long long int suma; poprz = S[--sptr]; suma = 0; while(sptr){ nast = S[--sptr]; if(nast%m == poprz%m + 1 || nast/m == poprz/m + 1) suma += a; if(nast%m == poprz%m - 1 || nast/m == poprz/m - 1) suma += b; poprz = nast; } if(suma_tot > suma){ suma_tot = suma; najlepsi = 1; } else if(suma_tot == suma) najlepsi++; delete [ ] d; delete [ ] p; delete [ ] QS; delete [ ] S; } cout << suma_tot << ' ' << najlepsi; return 0; } |