luoguP1967 貨車運輸
阿新 • • 發佈:2020-07-28
#include <bits/stdc++.h> using namespace std; template<typename temp> void read(temp &x){ x = 0; temp f = 1; char ch; while(!isdigit(ch = getchar())) (ch == '-') and (f = -1); for(x = ch^48; isdigit(ch = getchar()); x = (x<<3)+(x<<1)+(ch^48)); x *= f; } template<typename temp, typename ...res> void read(temp &a, res& ...some){read(a), read(some...);} const int maxn = 1e5; int n, m, q, num, fa[maxn], a[maxn]; pair<pair<int,int>, int> e[maxn]; vector<pair<int,int> >v[maxn]; vector<pair<pair<int,int>, int> >qwq; struct poutree{ #define ls (now << 1) #define rs (now<<1|1) #define mid ((l+r)>>1) int cnt, fa[maxn], dep[maxn], height_son[maxn], top[maxn], dfn[maxn], id[maxn], size[maxn]; struct no{ int l, r, minnum; }node[maxn<<2]; void build_poutree(int now){ size[now] = 1; for(int i = 0; i < v[now].size(); i ++){ int to = v[now][i].first; if(dep[to]) continue; dep[to] = dep[fa[to] = now] + 1; build_poutree(to); size[now] += size[to]; if(size[to] > size[height_son[now]]) height_son[now] = to; } } void dfs(int now, int topfa){ top[id[dfn[now]=++cnt]=now] = topfa; if(height_son[now]) dfs(height_son[now],topfa); for(int i = 0; i < v[now].size(); i ++){ int to = v[now][i].first; if(fa[now] == to or to == height_son[now]) continue; dfs(to,to); } } inline void up(int now){return(void)(node[now].minnum = min(node[ls].minnum, node[rs].minnum));} void build_segtree(int l, int r, int now){ node[now].l = l, node[now].r = r; if(l == r) return(void)(node[now].minnum = a[l]); build_segtree(l, mid, ls), build_segtree(mid+1, r, rs); return up(now); } void quary(int l, int r, int now, int &ans){ if(node[now].l > r or node[now].r < l) return; if(l <= node[now].l and node[now].r <= r) return(void)(ans = min(ans, node[now].minnum)); quary(l, r, ls, ans), quary(l, r, rs, ans); return up(now); } int lca(int x, int y){ int tmp = 1<<30; while(top[x] != top[y]){ if(dep[top[x]] < dep[top[y]]) swap(x,y); quary(dfn[top[x]], dfn[x], 1, tmp); x = fa[top[x]]; } if(dep[x] < dep[y]) swap(x,y); quary(dfn[height_son[y]], dfn[x], 1, tmp); return tmp; } void build(){ for(int i = 1; i <= n; i ++){ if(!size[i]) build_poutree(i*(dep[i]=1)), dfs(i,i); } for(int i = 1; i <= n; i ++) a[i] = 1<<29; for(int i = 0; i < qwq.size(); i ++){ a[dfn[dep[qwq[i].first.first]<dep[qwq[i].first.second]?qwq[i].first.second:qwq[i].first.first]] = qwq[i].second; } return build_segtree(1,n,1); } }tree; inline void add_edge(int x, int y, int z){ v[x].push_back(make_pair(y,z)); v[y].push_back(make_pair(x,z)); return; } inline int find(int x){ if(fa[x] == x) return x; return fa[x] = find(fa[x]); } bool tmp(pair<pair<int,int>, int> a, pair<pair<int,int>, int> b){ return a.second > b.second; } signed main(){ read(n, m); for(int i = 1, x, y, z; i <= m; i ++){ read(x,y,z); e[i].first.first = x, e[i].first.second = y, e[i].second = z; } sort(e+1,e+m+1,tmp); for(int i = 1; i <= n; i ++) fa[i] = i; for(int i = 1; i <= m; i ++){ int fx = find(e[i].first.first), fy = find(e[i].first.second); if(fx == fy) continue; qwq.push_back(e[i]); fa[fx] = fy; add_edge(e[i].first.first, e[i].first.second, e[i].second); } tree.build(); read(q); for(int x, y; q; q --){ read(x,y); if(find(x) != find(y)){ printf("-1\n"); continue; }else printf("%d\n", tree.lca(x,y)); } return 0; }