联通起始点的边权范围就是这些边权的最大最小值,而边数为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;
}