#line 1 "template/template.hpp" #include #if __has_include() #include #endif using namespace std; using int64 = long long; const int64 infll = (1LL << 62) - 1; const int inf = (1 << 30) - 1; struct IoSetup { IoSetup() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(10); cerr << fixed << setprecision(10); } } iosetup; template ostream& operator<<(ostream& os, const pair& p) { os << p.first << " " << p.second; return os; } template istream& operator>>(istream& is, pair& p) { is >> p.first >> p.second; return is; } template ostream& operator<<(ostream& os, const vector& v) { for (size_t i = 0; i < v.size(); i++) { os << v[i] << (i + 1 != v.size() ? " " : ""); } return os; } template istream& operator>>(istream& is, vector& v) { for (T& in : v) is >> in; return is; } template bool chmax(T1& a, T2 b) { return a < b && (a = b, true); } template bool chmin(T1& a, T2 b) { return a > b && (a = b, true); } template vector make_v(size_t a) { return vector(a); } template auto make_v(size_t a, Ts... ts) { return vector(ts...))>(a, make_v(ts...)); } template enable_if_t == 0> fill_v(T& t, const V& v) { t = v; } template enable_if_t != 0> fill_v(T& t, const V& v) { for (auto& e : t) fill_v(e, v); } template struct FixPoint : F { explicit FixPoint(F&& f) : F(std::forward(f)) {} template decltype(auto) operator()(Args&&... args) const { return F::operator()(*this, std::forward(args)...); } }; template decltype(auto) MFP(F&& f) { return FixPoint{std::forward(f)}; } #line 2 "structure/union-find/union-find.hpp" #include #include #include #include struct UnionFind { std::vector data; UnionFind() = default; explicit UnionFind(std::size_t sz) : data(sz, -1) {} bool unite(int x, int y) { x = find(x), y = find(y); if (x == y) return false; // if (data[x] > data[y]) std::swap(x, y); data[x] += data[y]; data[y] = x; return true; } int find(int k) { if (data[k] < 0) return (k); return data[k] = find(data[k]); } int size(int k) { return -data[find(k)]; } bool same(int x, int y) { return find(x) == find(y); } std::vector> groups() { int n = (int)data.size(); std::vector> ret(n); for (int i = 0; i < n; i++) { ret[find(i)].emplace_back(i); } ret.erase( std::remove_if(ret.begin(), ret.end(), [&](const std::vector& v) { return v.empty(); }), ret.end()); return ret; } }; int main() { int N, M, Q; cin >> N >> M >> Q; vector< int > A(N); cin >> A; vector< tuple< int, int, int > > es(M); for (auto& [w, u, v]: es) { cin >> u >> v >> w; --u, --v; } ranges::sort(es); vector< int > s(Q), c(Q); for (int i = 0; i < Q; i++) { cin >> s[i] >> c[i]; --s[i]; } vector ok(Q, inf), ng(Q, -1), mid(Q, -1); for (int i = 0; i < 32; i++) { vector< pair< int, int > > ev; for (int j = 0; j < Q; j++) { mid[j] = (ok[j] + ng[j]) / 2; ev.emplace_back(mid[j], j); } ranges::sort(ev); int p = 0; vector< set< int > > st(N); UnionFind uf(N); for (int j = 0; j < N; j++) { st[j].emplace(A[j]); } for (auto[vs, j]: ev) { while (p < es.size() and get< 0 >(es[p]) <= vs) { auto[_, u, v] = es[p]; u = uf.find(u); v = uf.find(v); if (u != v) { if (st[u].size() < st[v].size()) { swap(u, v); } for (auto x : st[v]) st[u].emplace(x); st[v].clear(); uf.unite(u, v); } ++p; } auto u = uf.find(s[j]); if (st[u].size() >= c[j]) ok[j] = vs; else ng[j] = vs; } } for (auto& p : ok) { if (p == inf) cout << -1 << "\n"; else cout << p << "\n"; } }