将边按速度进行从小达到的排序,设i是最大速度的边,通过枚举比i小的边 for(j=i;j>=0;j--) 如果找到起点和终点在同一个集合里,更新min。
测试数据较小,枚举不会超时。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define maxn 400
#define INF 100000001
int father[maxn],rank[maxn],n;
struct Len
{
int start;
int end;
int speed;
}len[1015];
bool cmp(Len a,Len b)
{
return a.speed<b.speed;
}
void makeset()
{
int i;
for(i=1;i<=n;i++)
{
father[i]=i;
rank[i]=0;
}
}
int getfather(int v)
{
if (father[v]==v)
return v;
else
{
father[v]=getfather(father[v]);
return father[v];
}
}
void Union(int x,int y)
{
int fx,fy;
fx=getfather(x);
fy=getfather(y);
if(fy!=fx)
father[fx]=fy;
}
bool same(int x,int y)
{
return getfather(x)==getfather(y);
}
void judge(int x ,int y)
{
int fx,fy;
fx = getfather(x);
fy = getfather(y);
if (rank[fx]>rank[fy])
father[fy] = fx;
else
{
father[fx] = fy;
if(rank[fx]==rank[fy])
++rank[fy];
}
}
int main()
{
int m;
int min;
int i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0;i<m;i++)
scanf("%d%d%d",&len[i].start,&len[i].end,&len[i].speed);
sort(len,len+m,cmp);
int q,s,e;
int k,f;
scanf("%d",&q);
for(k=0;k<q;k++)
{
min=INF;
scanf("%d%d",&s,&e);
for(i=0;i<m;i++)
{
makeset();
for(j=i;j>=0;j--)
{
Union(len[j].start,len[j].end);
judge(len[j].start,len[j].end);
if(same(s,e))
{
if(min>len[i].speed-len[j].speed)
min=len[i].speed-len[j].speed;
break;
}
}
}
if(min!=INF)
printf("%d\n",min);
else
printf("-1\n");
}
}
return 0;
}