题意:给出一幅无向图,每次询问给出起点和终点,求起点到终点权值差最小的一条路,输出权值差;
思路:边按权值排序,利用并查集枚举每次能使起点终点联通的情况下权值差,并每次更新最小值;
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f int fa[500010],n,m; struct node { int u,v,val; friend bool operator<(const node &a,const node &b) { return a.val<b.val; } }arr[500010]; void init() { for(int i=0;i<n;i++) { fa[i]=i; } } int fin(int x) { if(fa[x]==x) return x; return fa[x]=fin(fa[x]); } void combine(int a,int b) { int t1=fin(a); int t2=fin(b); if(t1!=t2) fa[t2]=t1; } int main() { int i,j,k,a,b,q,ans,flag; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<m;i++) scanf("%d%d%d",&arr[i].u,&arr[i].v,&arr[i].val); sort(arr,arr+m);//按速度从小到大排序 scanf("%d",&q); for(i=0;i<q;i++) { scanf("%d%d",&a,&b); ans=INF; for(j=0;j<m;j++)//枚举恰能使两点联通的边数 { init(); for(k=j;k>=0;k--) { combine(arr[k].u,arr[k].v); if(fin(a)==fin(b)) { ans=min(ans,arr[j].val-arr[k].val);//联通时,求最小差值 } } } if(ans==INF) printf("-1 "); else printf("%d ",ans); } } return 0; }