#include #include #include #include #include #include #include int main() { int64_t n, m, q; std::cin >> n >> m >> q; std::vector < std::vector > > edges(n); for (int i = 0; i < m; i++) { int64_t u, v, t; std::cin >> u >> v >> t; edges[u - 1].push_back({ v - 1, t }); edges[v - 1].push_back({ u - 1, t }); } std::vector > > children(n); struct Visit { int next; int64_t cost; int prev; bool operator<(const Visit& other) const { return cost > other.cost; } }; std::vector visited(n); std::priority_queue pq; for (int i = 0; i < n; i++) { if (visited[i]) continue; pq.push({ i,0,-1 }); while (!pq.empty()) { Visit next = pq.top(); pq.pop(); if (visited[next.next]) continue; visited[next.next] = true; if (next.prev != -1) children[next.prev].push_back({next.next, next.cost}); for (auto nb : edges[next.next]) { if (!visited[nb.first]) pq.push({ nb.first, nb.second, next.next }); } } } int L = 0; int i = n; while (i > 0) { i /= 2; L++; } struct Prev { int idx; int64_t maxtoll; }; std::vector > up(n); for (int i = 0; i < n; i++) { up[i].resize(L); for(int j=0; j > childidxrange(n); int idx = 0; for(int i=0; i dfs; dfs.push_front(0); while(!dfs.empty()) { int next = dfs.front(); dfs.pop_front(); if(visited[next]) { childidxrange[next].second = idx-1; } else { visited[next] = true; childidxrange[next].first = idx++; dfs.push_front(next); for(auto it : children[next]) dfs.push_front(it.first); } } for(int i=0; i > queries(q); for(int i=0; i> a >> b; queries[i].first = a-1; queries[i].second = b-1; } std::vector firstanswers(q); std::vector secondanswers(q); struct Edge { int v1; int v2; int64_t cost; bool operator<(const Edge &other) const { return cost < other.cost; } }; std::map > queriestohandle; std::vector sortededges; for(int i=0; i bidx || childidxrange[a].second < bidx) { while(jmp >= 0) { if(up[a][jmp].idx == -1) { jmp--; continue; } if(childidxrange[up[a][jmp].idx].first <= bidx && bidx <= childidxrange[up[a][jmp].idx].second) { jmp--; continue; } val = std::max(val, up[a][jmp].maxtoll); a = up[a][jmp].idx; jmp--; } val = std::max(val, up[a][0].maxtoll); a = up[a][0].idx; } int64_t val2 = 0; if(b != a) { int aidx = childidxrange[a].first; jmp = L-1; while(jmp >= 0) { if(up[b][jmp].idx == -1) { jmp--; continue; } if(childidxrange[up[b][jmp].idx].first <= aidx && aidx <= childidxrange[up[b][jmp].idx].second) { jmp--; continue; } val2 = std::max(val2, up[b][jmp].maxtoll); b = up[b][jmp].idx; jmp--; } val2 = std::max(val2, up[b][0].maxtoll); b = up[b][0].idx; } firstanswers[i] = std::max(val, val2); auto it = queriestohandle.find(firstanswers[i]); ++it; if(it != queriestohandle.end()) it->second.push_back(i); else secondanswers[i] = n; } struct UnionFind { std::vector parent; std::vector compsize; UnionFind(int n) { parent.resize(n); compsize.resize(n); for(int i=0; i done; for(auto it : sortededges) { if(!done.count(it.cost)) { done.insert(it.cost); for(auto q : queriestohandle[it.cost]) { secondanswers[q] = uf.size(queries[q].first); } } uf.doUnion(it.v1, it.v2); } for(int i=0; i