#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <list> #include <queue> #include <set> #include <map> #include <numeric> #include <utility> #include <string> #include <sstream> #include <algorithm> #include <unordered_set> #include <unordered_map> #include "kollib.h" #include "message.h" using namespace std; unordered_set<int> points; vector<int> points2; unordered_map<int, pair< pair<int,int>, pair<int,int> > > dist; vector<pair<int,int> > queries; int n, m; int nn, id; pair<int,int> go(int a, int b) { int r = 0; while (!points.count(a)) { ++r; int t = FirstNeighbor(a); if (t == b) t = SecondNeighbor(a); b = a; a = t; } return make_pair(a, r); } pair<pair<int,int>, pair<int, int> > go(int i) { auto a = go(FirstNeighbor(i), i); auto b = go(SecondNeighbor(i), i); ++a.second; ++b.second; return make_pair(a, b); } int go2(int a, int b, int c) { int r = 0; while (a != c) { auto x = dist[a].first; if (x.first == b) { x = dist[a].second; } r += x.second; b = a; a = x.first; } return r; } int go2(int a, int b) { if (a == b) return 0; int r = min(dist[a].first.second + go2(dist[a].first.first, a, b), dist[a].second.second + go2(dist[a].second.first, a, b)); return r; } int main() { n = NumberOfStudents(); m = NumberOfQueries(); if (!m) return 0; nn = NumberOfNodes(); id = MyNodeId(); queries.clear(); queries.resize(m); points.clear(); points2.clear(); dist.clear(); for (int i = 0; i < m; ++i) { queries[i].first = QueryFrom(i + 1); queries[i].second = QueryTo(i + 1); if (points.insert(queries[i].first).second) points2.push_back(queries[i].first); if (points.insert(queries[i].second).second) points2.push_back(queries[i].second); } srand(1212121); int pn = min(800, m / 100); while (points.size() < pn) { int rnd = rand() % n + 1; if (points.insert(rnd).second) points2.push_back(rnd); } for (size_t i = id; i < points2.size(); i += nn) { if (id == nn - 1) { dist[points2[i]] = go(points2[i]); } else { auto r = go(points2[i]); PutInt(nn - 1, points2[i]); PutInt(nn - 1, r.first.first); PutInt(nn - 1, r.first.second); PutInt(nn - 1, r.second.first); PutInt(nn - 1, r.second.second); Send(nn - 1); } } if (id == nn - 1) { for (size_t i = 0; i < points2.size(); ++i) { if (i % nn == id) continue; int src = Receive(-1); int pi = GetInt(src); pair<pair<int, int>, pair<int, int> > p; p.first.first = GetInt(src); p.first.second = GetInt(src); p.second.first = GetInt(src); p.second.second = GetInt(src); dist[pi] = p; } for (int i = 0; i < m; ++i) { printf("%d\n", go2(queries[i].first, queries[i].second)); } } 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 | #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <list> #include <queue> #include <set> #include <map> #include <numeric> #include <utility> #include <string> #include <sstream> #include <algorithm> #include <unordered_set> #include <unordered_map> #include "kollib.h" #include "message.h" using namespace std; unordered_set<int> points; vector<int> points2; unordered_map<int, pair< pair<int,int>, pair<int,int> > > dist; vector<pair<int,int> > queries; int n, m; int nn, id; pair<int,int> go(int a, int b) { int r = 0; while (!points.count(a)) { ++r; int t = FirstNeighbor(a); if (t == b) t = SecondNeighbor(a); b = a; a = t; } return make_pair(a, r); } pair<pair<int,int>, pair<int, int> > go(int i) { auto a = go(FirstNeighbor(i), i); auto b = go(SecondNeighbor(i), i); ++a.second; ++b.second; return make_pair(a, b); } int go2(int a, int b, int c) { int r = 0; while (a != c) { auto x = dist[a].first; if (x.first == b) { x = dist[a].second; } r += x.second; b = a; a = x.first; } return r; } int go2(int a, int b) { if (a == b) return 0; int r = min(dist[a].first.second + go2(dist[a].first.first, a, b), dist[a].second.second + go2(dist[a].second.first, a, b)); return r; } int main() { n = NumberOfStudents(); m = NumberOfQueries(); if (!m) return 0; nn = NumberOfNodes(); id = MyNodeId(); queries.clear(); queries.resize(m); points.clear(); points2.clear(); dist.clear(); for (int i = 0; i < m; ++i) { queries[i].first = QueryFrom(i + 1); queries[i].second = QueryTo(i + 1); if (points.insert(queries[i].first).second) points2.push_back(queries[i].first); if (points.insert(queries[i].second).second) points2.push_back(queries[i].second); } srand(1212121); int pn = min(800, m / 100); while (points.size() < pn) { int rnd = rand() % n + 1; if (points.insert(rnd).second) points2.push_back(rnd); } for (size_t i = id; i < points2.size(); i += nn) { if (id == nn - 1) { dist[points2[i]] = go(points2[i]); } else { auto r = go(points2[i]); PutInt(nn - 1, points2[i]); PutInt(nn - 1, r.first.first); PutInt(nn - 1, r.first.second); PutInt(nn - 1, r.second.first); PutInt(nn - 1, r.second.second); Send(nn - 1); } } if (id == nn - 1) { for (size_t i = 0; i < points2.size(); ++i) { if (i % nn == id) continue; int src = Receive(-1); int pi = GetInt(src); pair<pair<int, int>, pair<int, int> > p; p.first.first = GetInt(src); p.first.second = GetInt(src); p.second.first = GetInt(src); p.second.second = GetInt(src); dist[pi] = p; } for (int i = 0; i < m; ++i) { printf("%d\n", go2(queries[i].first, queries[i].second)); } } return 0; } |