题目链接:
题解思路 :
用到kruskal算法的思想:
枚举这条路径最小的边作为kruskal算法的起始边
当某条边加入一个 边集 后满足起点和终点在一个集合,即可得到一个答案
这些答案的最小值即为answer
中间会用到几个剪枝
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 1550
#define maxx 0x3f3f3f3f
using namespace std;
struct node
{
int from,to,w;
friend bool operator<(const node a,node b)
{
return a.w<b.w;
}
} edge[2*MAXN];
int fa[MAXN];
int start,endd,n,m;
int ans;
int flag;
int min(int a,int b)
{
return a<b?a:b;
}
int Find(int x)
{
if(x==fa[x]?x:fa[x]=Find(fa[x]));
}
int kruskal(int s)
{
for(int i=0; i<n; i++)
fa[i]=i;
int d1,d2;
for(int i=s; i<m; i++)
{
d1=Find(edge[i].from);
d2=Find(edge[i].to);
if(d1!=d2)
{
fa[d1]=d2;
if(Find(start)==Find(endd))
return edge[i].w-edge[s].w;
}
if(edge[i].w-edge[s].w>ans) //剪枝
return maxx;
}
flag=0;//枚举完所有边 起点和终点仍不能连通
return maxx;
}
int main()
{
//#ifndef ONLINE_JUDGE
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
//#endif // ONLINE_JUDGE
while(~scanf("%d%d%d%d",&n,&m,&start,&endd))
{
ans=maxx;
for(int i=0; i<m; i++)
scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].w);
sort(edge,edge+m);
flag=1;
for(int i=0; i<m&&flag; i++)
ans=min(kruskal(i),ans);
printf("%d\n",ans);
}
return 0;
}