题目:https://odzkskevi.qnssl.com/8e16f8701018d0e3529ac3ca319e1f67?v=1502277241
最简单的kruskal,主要参考紫书代码
kruskal算法就是先给边按权值大小排序,然后从小到大遍历,用并查集判断边上的两个点是否在同一集合,如果不是的话将其添加进去,直到所有的点都加入到集合中。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=10000;
int u[maxn],v[maxn],w[maxn],r[maxn],p[105];
int n,m;
bool cmp(int a,int b)
{
return w[a]<w[b];
}
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
int kruskal()
{
int ans=INF,ok=0;
for(int i=1;i<=n;i++) p[i]=i;
for(int i=0;i<m;i++) r[i]=i;
sort(r,r+m,cmp); //间接排序
for(int i=0;i<m;i++)
{
int num=0;
for(int j=1;j<=n;j++) p[j]=j;
for(int j=i;j<m;j++)
{
int e=r[j],x=find(u[e]),y=find(v[e]);
if(x!=y)
{
p[x]=y;
num++;
}
if(num==n-1)
{
ans=min(ans,w[r[j]]-w[r[i]]);
ok=1;
break;
}
}
}
if(ok==1)
return ans;
else
return -1;
}
int main()
{
while(cin>>n>>m)
{
if(n==0)
break;
for(int i=0;i<m;i++)
cin>>u[i]>>v[i]>>w[i];
cout<<kruskal()<<endl;
}
}