算法
最小生成树
思路
其实就是一道最小生成树的模板题,我在这里用的是kruskal算法,唯一需要注意的是每加入一条边都要判断s,t是不是在一个集合里面,这样就可以顺利AC了。(排序了)
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int fa[10005];
struct node{
int x,y,z;
};
node way[20010];
int n,m,s,t,tot=0;
int com(const node &c,const node &d)
{
return c.z<d.z;
}
int find(int g) //找到该元素所在集合的代表元素
{
if (fa[g]!=g)
fa[g]=find(fa[g]);
return fa[g];
}
int unionn(int s1,int s2) //合并集合的过程
{
int r1=find(s1);
int r2=find(s2);
if (r1!=r2)
fa[r1]=r2;
}
int js()
{
int i,j,k;
k=1;
i=1;
while (k<n)
{
while (find(way[i].x)==find(way[i].y))
i++;
tot=max(way[i].z,tot); //因为求的是最大值,所以用了一个max,其实没必要这么麻烦,因为边一定是从大到小的,后加入的边一定较大,可以直接写tot=way[i].z;
unionn(way[i].x,way[i].y); //这里就是一个并查集处理
k++;
if (find(s)==find(t)) //判断,自认为是这道题最重要的细节
break;
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
int i;
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&way[i].x,&way[i].y,&way[i].z);
}
for (i=1;i<=n;i++)
fa[i]=i;
sort(way+1,way+1+m,com); //把边从小到大排序
js();
printf("%d",tot);
return 0;
}