很神奇的kruakal用法,枚举最小的边,然后kruakal找到一条可行路径,记录差值比较
看了解题报告都有点晕,自己绝对想不到这种用法。。。。。
code:
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 0x3fffffff;
int n,m,fa[201],rank[201];
struct node
{
int from,to,w;
}p[1001];
bool cmp(const node x,const node y)
{
return x.w<y.w;
}
int find(int k)
{
if(k!=fa[k])
{
fa[k]=find(fa[k]);
}
return fa[k];
}
void merge(int x,int y)
{
if(x==y)
{
return ;
}
if(rank[x]<rank[y])
{
fa[x]=y;
}else{
fa[y]=x;
if(rank[x]==rank[y])
{
rank[x]++;
}
}
}
int main()
{
int i,j,a,b,x,y,ans,cas;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&p[i].from,&p[i].to,&p[i].w);
}
sort(p+1,p+m+1,cmp);
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&a,&b);
ans=INF;
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
fa[j]=j;
rank[j]=0;
}
for(j=i;j<=m;j++)
{
x=find(p[j].from);
y=find(p[j].to);
merge(x,y);
if(find(a)==find(b))
{
x=p[j].w-p[i].w;
if(x<ans)
{
ans=x;
}
break;
}
}
if(j==m+1)
{
break;
}
}
if(ans==INF)
{
puts("-1");
}else{
printf("%d\n",ans);
}
}
}
return 0;
}