联通起始点的边权范围就是这些边权的最大最小值,而边数为1000,所以可以枚举这个范围,然后判断对于每一个范围是否联通。进一步的,可以枚举最小值并依此加入更长边,直到起始点联通,得到该最小值下的最优解。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
using namespace std;
#define pb push_back
#define INF (1<<30)
struct edge {
int u,v,len;
edge(){}
edge(int a,int b,int c):u(a),v(b),len(c){}
bool operator<(const edge &obj) const {
return len < obj.len;
}
};
vector<edge> e;
int bc[201],n,m;
int find(int p) {
if(!bc[p]) return p;
return bc[p]=find(bc[p]);
}
void uni(const edge &obj) {
int i=find(obj.u),j=find(obj.v);
if(i!=j) bc[i]=j;
}
int solve(int s,int t) {
int res=INF;
for(int i=0;i<m;++i) {
memset(bc,0,sizeof(bc));
for(int j=i;j<m;++j) {
uni(e[j]);
if(find(s)==find(t)) {res=min(res,e[j].len - e[i].len);break;}
}
}
return res==INF?-1:res;
}
int main() {
ios::sync_with_stdio(false);
while(cin >> n >> m) {
e.clear();
for(int i=0;i<m;++i) {
int a,b,c;
cin >> a >> b >> c;
e.pb(edge(a,b,c));
}
sort(e.begin(),e.end());
int Q;
cin >> Q;
while(Q--) {
int a,b;
cin >> a >> b;
cout << solve(a,b) << endl;
}
}
return 0;
}