#include <iostream> #include <algorithm> #include <set> #include <vector> #ifdef HOME_ #define DEBUG(x) x #else #define DEBUG(x) #endif #define REP(x,n) for(int x=0;x<(n);++x) #define FOREACH(x,n) for(__typeof(n.begin()) x = (n).begin(); x != (n).end(); ++x) using namespace std; const int MAX_N = 2001; const long long BILLION = 1000000000LL; int n,m,k; int a,b; typedef pair<int,int> PII; struct Info { long long distance; pair<int,int> prev; char iteration; Info(): distance(0x7FFFFFFFFFFFFFFFLL), iteration(0) {} }; string vertex[MAX_N]; Info dist[MAX_N][MAX_N]; long long dist11, dist12, dist21, dist22; struct compare { bool operator()(const PII& a, const PII& b) const { const Info& ia = dist[a.first][a.second]; const Info& ib = dist[b.first][b.second]; return ia.iteration != ib.iteration ? ia.iteration < ib.iteration : ia.distance != ib.distance ? ia.distance < ib.distance : a.first == b.first ? a.second<b.second : a.first<b.first; } }; #define PROCESS(x,y,w) DEBUG(cerr << "check " << (x)<<","<<(y)<<" - "<<((x>=0)&&(y>=0) ? vertex[x][y] : '/')<<endl;) \ if ((x)>=0 && (y)>=0 && (x)<n && (y)<m && vertex[x][y]=='.') {\ Info& i = dist[x][y];\ if (i.iteration != cycle) {\ i.iteration = cycle;\ i.distance = topi.distance + w;\ i.prev = top;\ q.insert(make_pair(x,y));\ } else if (i.distance > topi.distance+w) {\ q.erase(make_pair(x,y));\ i.distance = topi.distance + w;\ i.prev = top;\ q.insert(make_pair(x,y));\ }\ } void processGraph(char cycle, long long w1, long long w2) { dist[0][0].iteration = cycle; dist[0][0].distance = 0LL; set<PII, compare> q; q.insert(make_pair(0,0)); while(!q.empty()) { PII top = *q.begin(); Info& topi = dist[top.first][top.second]; q.erase(q.begin()); DEBUG( cerr << "Procesing " << top.first<< "," << top.second << ", dist=" << topi.distance << endl; ) if (top.first == n-1 && top.second == m-1) break; // reached end point PROCESS(top.first-1, top.second, w1); PROCESS(top.first, top.second-1, w1); PROCESS(top.first+1, top.second, w2); PROCESS(top.first, top.second+1, w2); DEBUG( cerr << "After processing: " <<endl; FOREACH(it, q) cerr << "("<<it->first<<","<<it->second<<"), "; cerr<<endl; ) } } void processGraph() { processGraph(1, 1, BILLION); dist11 = dist[n-1][m-1].distance / BILLION; dist12 = dist[n-1][m-1].distance % BILLION; processGraph(2, BILLION, 1); dist21 = dist[n-1][m-1].distance % BILLION; dist22 = dist[n-1][m-1].distance / BILLION; } long long calculate(int a, int b) { DEBUG( cerr << a << "/" << b << "->" << dist11 << "/" << dist12 << " or " << dist21 << "/" << dist22 << endl; ) if (a<b || (a==b && dist11 < dist12)) return ((long long)a)*dist11 + ((long long)b)*dist12; else return ((long long)a)*dist21 + ((long long)b)*dist22; return 0; } int main() { ios_base::sync_with_stdio(0); cin>>n>>m>>k; REP(x,n) cin>>vertex[x]; processGraph(); long long minResult=0x7fffffffffffffffLL, localRes; int minCnt=0; REP(x,k) { cin>>a>>b; localRes = calculate(a,b); if (localRes < minResult) { minResult = localRes; minCnt = 1; } else if (localRes == minResult) ++minCnt; } cout << minResult << " " << minCnt; 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 | #include <iostream> #include <algorithm> #include <set> #include <vector> #ifdef HOME_ #define DEBUG(x) x #else #define DEBUG(x) #endif #define REP(x,n) for(int x=0;x<(n);++x) #define FOREACH(x,n) for(__typeof(n.begin()) x = (n).begin(); x != (n).end(); ++x) using namespace std; const int MAX_N = 2001; const long long BILLION = 1000000000LL; int n,m,k; int a,b; typedef pair<int,int> PII; struct Info { long long distance; pair<int,int> prev; char iteration; Info(): distance(0x7FFFFFFFFFFFFFFFLL), iteration(0) {} }; string vertex[MAX_N]; Info dist[MAX_N][MAX_N]; long long dist11, dist12, dist21, dist22; struct compare { bool operator()(const PII& a, const PII& b) const { const Info& ia = dist[a.first][a.second]; const Info& ib = dist[b.first][b.second]; return ia.iteration != ib.iteration ? ia.iteration < ib.iteration : ia.distance != ib.distance ? ia.distance < ib.distance : a.first == b.first ? a.second<b.second : a.first<b.first; } }; #define PROCESS(x,y,w) DEBUG(cerr << "check " << (x)<<","<<(y)<<" - "<<((x>=0)&&(y>=0) ? vertex[x][y] : '/')<<endl;) \ if ((x)>=0 && (y)>=0 && (x)<n && (y)<m && vertex[x][y]=='.') {\ Info& i = dist[x][y];\ if (i.iteration != cycle) {\ i.iteration = cycle;\ i.distance = topi.distance + w;\ i.prev = top;\ q.insert(make_pair(x,y));\ } else if (i.distance > topi.distance+w) {\ q.erase(make_pair(x,y));\ i.distance = topi.distance + w;\ i.prev = top;\ q.insert(make_pair(x,y));\ }\ } void processGraph(char cycle, long long w1, long long w2) { dist[0][0].iteration = cycle; dist[0][0].distance = 0LL; set<PII, compare> q; q.insert(make_pair(0,0)); while(!q.empty()) { PII top = *q.begin(); Info& topi = dist[top.first][top.second]; q.erase(q.begin()); DEBUG( cerr << "Procesing " << top.first<< "," << top.second << ", dist=" << topi.distance << endl; ) if (top.first == n-1 && top.second == m-1) break; // reached end point PROCESS(top.first-1, top.second, w1); PROCESS(top.first, top.second-1, w1); PROCESS(top.first+1, top.second, w2); PROCESS(top.first, top.second+1, w2); DEBUG( cerr << "After processing: " <<endl; FOREACH(it, q) cerr << "("<<it->first<<","<<it->second<<"), "; cerr<<endl; ) } } void processGraph() { processGraph(1, 1, BILLION); dist11 = dist[n-1][m-1].distance / BILLION; dist12 = dist[n-1][m-1].distance % BILLION; processGraph(2, BILLION, 1); dist21 = dist[n-1][m-1].distance % BILLION; dist22 = dist[n-1][m-1].distance / BILLION; } long long calculate(int a, int b) { DEBUG( cerr << a << "/" << b << "->" << dist11 << "/" << dist12 << " or " << dist21 << "/" << dist22 << endl; ) if (a<b || (a==b && dist11 < dist12)) return ((long long)a)*dist11 + ((long long)b)*dist12; else return ((long long)a)*dist21 + ((long long)b)*dist22; return 0; } int main() { ios_base::sync_with_stdio(0); cin>>n>>m>>k; REP(x,n) cin>>vertex[x]; processGraph(); long long minResult=0x7fffffffffffffffLL, localRes; int minCnt=0; REP(x,k) { cin>>a>>b; localRes = calculate(a,b); if (localRes < minResult) { minResult = localRes; minCnt = 1; } else if (localRes == minResult) ++minCnt; } cout << minResult << " " << minCnt; return 0; } |