http://pipioj.online/problem.php?id=1484
思路:和这道题很像,暴力跑克鲁斯卡尔即可。想法就是,对边按照速度从小到大排序,从速度最小的边开始暴力枚举,那么当目标点
s
、
t
s、t
s、t连通时最大的边也确定了。复杂度大概在
O
(
q
m
2
)
O(qm^2)
O(qm2),可过。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxm=2e3+5;
struct Edge
{
int u,v,s;
Edge(int u=0,int v=0,int s=0):u(v),v(v),s(s){}
bool operator <(const Edge &e)const
{
return s<e.s;
}
}edge[maxm];
int n,m,q,s,t;
int f[505];
int father(int x)
{
return f[x]==x?x:f[x]=father(f[x]);
}
inline void init()
{
for(int i=1;i<=n;i++)
f[i]=i;
}
inline void uni(int x,int y)
{
int fx=father(x),fy=father(y);
if(fx!=fy)
f[fx]=fy;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%d %d %d %d",&edge[i].u,&edge[i].v,&edge[i].s,&q);
sort(edge,edge+m);
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&s,&t);
int ans=INF;
for(int i=0;i<m;i++)
{
init();
for(int j=i;j<m;j++)
{
uni(edge[j].u,edge[j].v);
if(father(s)==father(t))
{
ans=min(ans,edge[j].s-edge[i].s);
break;
}
}
if(ans==INF)
{
ans=-1;
break;
}
}
printf("%d\n",ans);
}
return 0;
}