kruskal
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
int k=0,tot=0;
int fa[100012];
struct str{
int from,to,dis;//起点,终点,边的权值
}map[200012];
bool comdis(str a,str b)
{
return a.dis<b.dis;
}
int father(int x)
{
if(fa[x]==x)
return x;
else{
return father(fa[x]);
}
}
void unionn(int x,int y)
{
fa[father(y)]=father(x);//把x这个元素加入y的队中
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&map[i].from,&map[i].to,&map[i].dis);
}
for(int i=1;i<=n;i++)
{
fa[i]=i;
}
sort(map+1,map+1+m,comdis);
for(int i=1;i<=m;i++)//对边进行操作,从最小的开始
{
if(k==(n-1))break;
if(father(map[i].from)!=father(map[i].to))
{
unionn(map[i].from,map[i].to);
k++;//已经加入集合的边数++
tot+=map[i].dis;
}
}
printf("%d",tot);
}
prim
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
#define INF 123456789
int tot=0,head[200005],to[200005],wei[200005],next[200005];
void add(int x,int y,int z)
{
tot++;
to[tot]=y;
next[tot]=head[x];
head[x]=tot;
wei[tot]=z;
}
int cnt=0;
int dis[200005];
int n,m,now=1,ans;
bool vis[200005];
int prim()
{
for(int i=2;i<=n;++i)
{
dis[i]=INF;
}
for(int i=head[1];i;i=next[i])
{
int v=to[i];
dis[v]=min(dis[v],wei[i]);
}
while(++cnt<n)//最小生成树边数等于点数-1
{
int minn=INF;//把minn置为极大值
vis[now]=1;//标记点已经走过
//枚举每一个没有使用的点
//找出最小值作为新边
//注意这里不是枚举now点的所有连边,而是1~n
for(int i=1;i<=n;++i)
{
if(!vis[i]&&minn>dis[i])
{
minn=dis[i];
now=i;
}
}
ans+=minn;
//枚举now的所有连边,更新dis数组
for(int i=head[now];i;i=next[i])
{
int v=to[i];
if(dis[v]>wei[i]&&!vis[v])
{
dis[v]=wei[i];
}
}
}
return ans;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v,z;
cin>>u>>v>>z;
add(u,v,z);
add(v,u,z);
}
prim();
cout<<ans<<endl;
return 0;
}