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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
| #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cctype> #include <vector> #include <queue> #define ll long ong #define ri register int #define ull unsigned long long using std::vector; using std::swap; using std::min; using std::max; using std::sort; template <class T>inline void read(T &x){ x=0;int ne=0;char c; while(!isdigit(c=getchar()))ne=c=='-'; x=c-48; while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48; x=ne?-x:x;return ; } const int maxn=10005; const int maxm=50005; const int inf=0x7fffffff; int n,m; struct Edge{ int x,y,c; Edge(int _x,int _y,int _c){x=_x,y=_y,c=_c;} Edge(){x=y=c=0;} bool operator <(const Edge &b)const { return c>b.c; } }edge[maxm]; struct Dat{ int ver,dis; Dat(int x,int y){ver=x,dis=y;} Dat(){;} }; vector<Dat>g[maxn]; int pa[maxn]; int get(int x){ if(pa[x]!=x)pa[x]=get(pa[x]); return pa[x]; } inline void kruskal(){ int cnt=0,x,y,xx,yy,c; sort(edge+1,edge+1+m); for(ri i=1;i<=n;i++)pa[i]=i; for(ri i=1;i<=m;i++){ int x=edge[i].x,y=edge[i].y; xx=get(x),yy=get(y); if(xx==yy)continue; c=edge[i].c; g[x].push_back(Dat(y,c)); g[y].push_back(Dat(x,c)); pa[xx]=yy; cnt++; if(cnt==n-1)break; } return ; } int dep[maxn],son[maxn],top[maxn],size[maxn],dfn[maxn],fa[maxn],rnk[maxn],tot=0; int w[maxn]; void dfs_1(int now){ int v;size[now]=1; for(ri i=0;i<g[now].size();i++){ v=g[now][i].ver; if(v==fa[now])continue; fa[v]=now,dep[v]=dep[now]+1; w[v]=g[now][i].dis; dfs_1(v); size[now]+=size[v]; if(!son[now]||size[v]>size[son[now]])son[now]=v; } return ; } void dfs_2(int now,int t){ int v;dfn[now]=++tot,rnk[tot]=now,top[now]=t; if(!son[now])return ; dfs_2(son[now],t); for(ri i=0;i<g[now].size();i++){ v=g[now][i].ver; if(v==fa[now]|v==son[now])continue; dfs_2(v,v); } return ; } int mi[maxn<<2]; void build(int now,int l,int r){ if(l==r){ mi[now]=w[rnk[l]]; return ; } int mid=(l+r)>>1; build(now<<1,l,mid); build(now<<1|1,mid+1,r); mi[now]=min(mi[now<<1],mi[now<<1|1]); return ; } int L,R; int query(int now,int l,int r){ if(L<=l&&r<=R){ return mi[now]; } int ans=inf,mid=(l+r)>>1; if(L<=mid)ans=min(ans,query(now<<1,l,mid)); if(mid<R)ans=min(ans,query(now<<1|1,mid+1,r)); return ans; } inline int query_path(int x,int y){ int ans=inf; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); L=dfn[top[x]],R=dfn[x]; ans=min(ans,query(1,1,n)); x=fa[top[x]]; } if(dfn[x]>dfn[y])swap(x,y); L=dfn[x]+1,R=dfn[y]; if(L>R)return ans; ans=min(ans,query(1,1,n)); return ans; } int main(){ int q,x,y,z; read(n),read(m); for(ri i=1;i<=m;i++){ read(x),read(y),read(z); edge[i]=Edge(x,y,z); } kruskal(); for(ri i=1;i<=n;i++){ if(!dfn[i]){ dep[i]=1,fa[i]=0; dfs_1(i); dfs_2(i,i); } } build(1,1,n); read(q); while(q--){ read(x),read(y); int tmp=query_path(x,y); if(!tmp)puts("-1"); else printf("%d\n",tmp); } return 0; }
|