Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define cin_2d(vec, n, m) for(int i = 0; i < n; i++) for(int j = 0; j < m && cin >> vec[i][j]; j++);
- #define cout_2d(vec, n, m) for(int i = 0; i < n; i++, cout << "\n") for(int j = 0; j < m && cout << vec[i][j] << " "; j++);
- #define cout_map(mp) for(auto& [f, s] : mp) cout << f << " " << s << "\n";
- #define Time cerr << "Time Taken: " << (float)clock() / CLOCKS_PER_SEC << " Secs" << "\n";
- #define fixed(n) fixed << setprecision(n)
- #define ceil(n, m) (((n) / (m)) + ((n) % (m) ? 1 : 0))
- #define fill(vec, value) memset(vec, value, sizeof(vec));
- #define Num_of_Digits(n) ((int)log10(n) + 1)
- #define mod_combine(a, b, m) (((a % m) * (b % m)) % m)
- #define all(vec) vec.begin(), vec.end()
- #define rall(vec) vec.rbegin(), vec.rend()
- #define sz(x) int(x.size())
- #define debug(x) cout << #x << ": " << (x) << "\n";
- #define fi first
- #define se second
- #define ll long long
- #define ull unsigned long long
- #define Mod 1'000'000'007
- #define OO 2'000'000'000
- #define EPS 1e-9
- #define PI acos(-1)
- template < typename T = int > using Pair = pair < T, T >;
- template < typename T = int > istream& operator >> (istream &in, vector < T > &v) {
- for (auto &x: v) in >> x;
- return in;
- }
- template < typename T = int > ostream& operator << (ostream &out, const vector < T > &v) {
- for (const T &x: v) out << x << ' ';
- return out;
- }
- struct DSU {
- vector < int > parent, Gsize;
- DSU(int MaxNodes){
- parent.resize(MaxNodes + 5);
- Gsize.resize(MaxNodes + 5);
- for(int i = 1; i <= MaxNodes; i++)
- parent[i] = i, Gsize[i] = 1;
- }
- int find_leader(int node){
- return parent[node] = (parent[node] == node ? node : find_leader(parent[node]));
- }
- bool is_same_sets(int u, int v){
- return find_leader(u) == find_leader(v);
- }
- void union_sets(int u, int v){
- int leader_u = find_leader(u), leader_v = find_leader(v);
- if(leader_u == leader_v) return;
- if(Gsize[leader_u] < Gsize[leader_v]) swap(leader_u, leader_v);
- Gsize[leader_u] += Gsize[leader_v], parent[leader_v] = leader_u;
- }
- int get_size(int node){
- return Gsize[find_leader(node)];
- }
- };
- struct Edge {
- int u, v, w;
- Edge(int U = 0, int V = 0, int W = 0) : u(U), v(V), w(W) {}
- bool operator < (const Edge &e) const {
- return w > e.w;
- }
- };
- constexpr int N = 1e4;
- int n, m;
- vector < int > dep(N + 10);
- vector < vector < Pair < int > > > adj(N + 10);
- vector < vector < int > > anc(N + 10, vector < int > (20)), cost(N + 10, vector < int > (20));
- int k_ancestor(int node, int dist){
- if(dep[node] <= dist) return -1;
- for(int bit = 0; bit < 20; bit++)
- if(dist & (1 << bit))
- node = anc[node][bit];
- return node;
- }
- int combine(int u, int v){
- return min(u, v);
- }
- void dfs(int node, int par, int c){
- dep[node] = dep[par] + 1, anc[node][0] = par, cost[node][0] = c;
- for(int bit = 1; bit < 20; bit++){
- anc[node][bit] = anc[anc[node][bit - 1]][bit - 1];
- cost[node][bit] = min(cost[node][bit - 1], cost[anc[node][bit - 1]][bit - 1]);
- }
- for(auto& [new_node, value] : adj[node])
- if(new_node != par)
- dfs(new_node, node, value);
- }
- int lca(int u, int v){
- if(dep[u] > dep[v])
- swap(u, v);
- v = k_ancestor(v, dep[v] - dep[u]);
- if(u == v) return u;
- for(int bit = 19; bit >= 0; bit--)
- if(anc[u][bit] != anc[v][bit])
- u = anc[u][bit], v = anc[v][bit];
- return anc[u][0];
- }
- int get_cost(int node, int dist){
- if(dep[node] <= dist) return -1;
- int ans = OO;
- for(int bit = 0; bit < 20; bit++)
- if(dist & (1 << bit))
- ans = combine(ans, cost[node][bit]), node = anc[node][bit];
- return ans;
- }
- int query(int u, int v){
- if(dep[u] > dep[v])
- swap(u, v);
- int LCA = lca(u, v);
- return combine(get_cost(u, dep[u] - dep[LCA]), get_cost(v, dep[v] - dep[LCA]));
- }
- void Solve(){
- cin >> n >> m;
- vector < Edge > edges(m);
- for(auto& e : edges)
- cin >> e.u >> e.v >> e.w;
- sort(all(edges));
- DSU dsu(n);
- for(auto& e : edges){
- if(dsu.is_same_sets(e.u, e.v))
- continue;
- dsu.union_sets(e.u, e.v);
- adj[e.u].push_back({e.v, e.w}), adj[e.v].push_back({e.u, e.w});
- }
- dfs(1, 0, 0);
- int q;
- cin >> q;
- while(q--){
- int u, v;
- cin >> u >> v;
- cout << query(u, v) << '\n';
- }
- }
- int main(){
- ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
- int t = 1;
- //cin >> t;
- while(t--)
- Solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement