1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int MAXN=50001; 8 int n,m; 9 int x,y,z; 10 struct node 11 { 12 int u,v,w,next; 13 }edge[MAXN],a[MAXN]; 14 int num=1; 15 int head[MAXN]; 16 int f[MAXN]; 17 int anum=1; 18 int ahead[MAXN]; 19 int deep[MAXN]; 20 int s[MAXN][20]; 21 int take[MAXN][20]; 22 void edge_add(int x,int y,int z) 23 { 24 edge[num].u=x; 25 edge[num].v=y; 26 edge[num].w=z; 27 edge[num].next=head[x]; 28 head[x]=num++; 29 } 30 void a_add(int i) 31 { 32 a[anum].u=edge[i].u; 33 a[anum].v=edge[i].v; 34 a[anum].w=edge[i].w; 35 a[anum].next=ahead[a[anum].u]; 36 ahead[a[anum].u]=anum++; 37 } 38 int comp(const node & a ,const node & b) 39 {return a.w>b.w;} 40 41 int find(int x) 42 { 43 if(f[x]!=x) 44 f[x]=find(f[x]); 45 return f[x]; 46 } 47 void unionn(int x,int y) 48 { 49 int fx=find(x); 50 int fy=find(y); 51 f[fx]=fy; 52 } 53 void Biggest_Kruskal() 54 { 55 sort(edge+1,edge+num,comp); 56 int k=0; 57 for(int i=1;i<num;i++) 58 { 59 int uu=edge[i].u; 60 int vv=edge[i].v; 61 if(find(uu)!=find(vv)) 62 { 63 unionn(uu,vv); 64 a_add(i); 65 k++; 66 } 67 if(k==n-1)break; 68 } 69 for(int i=1;i<=anum;i++) 70 cout<<a[i].u<<" "<<a[i].v<<" "<<a[i].w<<" "<<a[i].next<<endl; 71 } 72 void Build_Tree(int p) 73 { 74 for(int i=ahead[p];i!=-1;i=a[i].next) 75 { 76 int will=a[i].v; 77 if(deep[will]==0) 78 { 79 deep[will]=deep[p]+1; 80 s[will][0]=p; 81 take[will][0]=a[i].w; 82 Build_Tree(will); 83 } 84 } 85 } 86 void Initialize_Step() 87 { 88 for(int i=1;i<=19;i++) 89 { 90 for(int j=1;j<=n;j++) 91 { 92 s[j][i]=s[s[j][i-1]][i-1]; 93 take[j][i]=min(take[j][i-1],take[s[j][i-1]][i-1]); 94 } 95 } 96 } 97 int LCA(int x,int y) 98 { 99 int ans=0x7ff; 100 if(deep[x]<deep[y]) 101 swap(x,y); 102 for(int i=19;i>=0;i--) 103 { 104 if(deep[s[x][i]]>=deep[y]) 105 x=s[x][i]; 106 } 107 if(x==y) 108 return x; 109 for(int i=19;i>=0;i--) 110 { 111 if(s[x][i]!=s[y][i]) 112 { 113 x=s[x][i]; 114 y=s[y][i]; 115 ans=min(ans,take[x][i]); 116 ans=min(ans,take[y][i]); 117 } 118 } 119 ans=min(ans,take[x][0]); 120 ans=min(ans,take[y][0]); 121 return ans; 122 } 123 int main() 124 { 125 scanf("%d%d",&n,&m); 126 127 for(int i=1;i<=n;i++) 128 {head[i]=-1;f[i]=i;ahead[i]=-1;} 129 130 for(int i=1;i<=m;i++) 131 { 132 scanf("%d%d%d",&x,&y,&z); 133 edge_add(x,y,z); 134 //edge_add(y,x,z); 135 } 136 Biggest_Kruskal(); 137 deep[1]=1; 138 for(int i=1;i<=n;i++) 139 Build_Tree(i); 140 Initialize_Step(); 141 int q; 142 scanf("%d",&q); 143 for(int i=1;i<=q;i++) 144 { 145 int x,y; 146 scanf("%d%d",&x,&y); 147 if(find(x)!=find(y)) 148 { 149 printf("-1\n"); 150 continue; 151 } 152 printf("%d\n",LCA(x,y)); 153 } 154 return 0; 155 }