洛谷P3366

用kruskal(prim不会。。。才不是因为懒呢)

kruskal大概思路:首先找到一条权值最小的边,将他的两个点加入集合中,然后继续往下找小边,

用并查集算法判断一下是否在统一集合内,如果是的话,就不加入;

不是就加入集合并累计入答案。。。

#include<bits/stdc++.h>

using namespace std;

struct node{

  int x,y,c; }a[500010]; int n,m,fa[500010],ans,t; int getfa(int x){//寻找祖先 if(fa[x]==x) return x; else{ fa[x]=getfa(fa[x]); return fa[x]; } } bool cmp(node a,node b){ return a.c<b.c; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) fa[i]=i;//并查集初始化,刚开始所有点的父亲都是自己,单独成一个集合 for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].c);   sort(a+1,a+m+1,cmp); for(int i=1;i<=m;i++){ int fx,fy; fx=getfa(a[i].x); fy=getfa(a[i].y); if(fx!=fy){//不在同一集合内就累计入答案 ans+=a[i].c; t++; fa[fy]=fx;//加入集合,认x的祖先点为父亲 if(t==n-1) break;//招满了n-1条边,就已经完成任务了 } } printf("%d",ans); return 0; }
原文地址:https://www.cnblogs.com/heqingyu/p/7682773.html