@OceanEye7年前
07/11
15:00
为什么我在写这题的题解……
因为这题我本来想用树剖搞过去的……结果炸了
:-D然后就写了现在的倍增
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 |
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #define ll long long #define INF 10000000 #define For(i,a,b) for(int i=a;i<=b;i++) #define p(c) (c>='0'&&c<='9') char cc; int C; template <class T> void read(T &x) { x=0; cc=getchar(); C=1; while(!p(cc)) { if(cc=='-') C=-1; cc=getchar(); } while(p(cc)) { x=x*10+cc-48; cc=getchar(); } x*=C; } using namespace std; #define N 10010 #define M 50010 struct rec { int u,v,val; bool operator < (const rec &x) const { return val>x.val; } }REC[M]; struct UNF { int fa[N],siz[N]; void init(int n) { For(i,1,n) fa[i]=i,siz[i]=1; } int getfa(int x) { return fa[x]==x?x:fa[x]=getfa(fa[x]); } bool combine(int u,int v) { u=getfa(u); v=getfa(v); if(u==v) return false; siz[u]<siz[v]?swap(u,v):swap(u,u); fa[v]=u; siz[u]+=siz[v]; return true; } bool test(int u,int v) { return getfa(u)==getfa(v); } }UNF_set; struct Tedge { int to,val; }edge[N<<1]; int fst[N],nxt[N<<1],e_tot; #define TO edge[i].to #define VAL edge[i].val #define NXT nxt[i] void add_e(int a,int b,int val) { static int &i=e_tot; TO=b; VAL=val; NXT=fst[a]; fst[a]=i++; TO=a; VAL=val; NXT=fst[b]; fst[b]=i++; } int val[N],fa[N][15],mn[N][15],dep[N],n,m; void dfs(int x,int f) { fa[x][0]=f; mn[x][0]=val[x]; for(int i=1;i<15;i++) { fa[x][i]=fa[fa[x][i-1]][i-1]; mn[x][i]=min(mn[x][i-1],mn[fa[x][i-1]][i-1]); } for(int i=fst[x];~i;i=NXT) { if(TO==f) continue; val[TO]=VAL; dep[TO]=dep[x]+1; dfs(TO,x); } } int getLCA(int u,int v) { if(dep[u]>dep[v]) swap(u,v); int dis=dep[v]-dep[u]; for(int i=14;i>=0;i--) if((1<<i)&dis) v=fa[v][i]; if(u==v) return u; for(int i=14;i>=0;i--) if(fa[u][i]==fa[v][i]) continue; else u=fa[u][i],v=fa[v][i]; return fa[u][0]; } void init() { memset(fst,-1,sizeof(fst)); read(n); read(m); For(i,1,m) { read(REC[i].u); read(REC[i].v); read(REC[i].val); } sort(REC+1,REC+1+m); UNF_set.init(n); For(i,1,m)if(UNF_set.combine(REC[i].u,REC[i].v)) add_e(REC[i].u,REC[i].v,REC[i].val); } int main() { init(); int ans,u,v,p; for(int i=1;i<=n;i++) if(!val[i]) { val[i]=INF; dfs(i,0); } for(read(m);m;m--) { read(u); read(v); if(!UNF_set.test(u,v)) { puts("-1"); continue; } p=getLCA(u,v); ans=INF; for(int i=14;i>=0;i--) { if((dep[u]-dep[p])&(1<<i)) ans=min(ans,mn[u][i]),u=fa[u][i]; if((dep[v]-dep[p])&(1<<i)) ans=min(ans,mn[v][i]),v=fa[v][i]; } printf("%d\n",ans); } return 0; } |