UOJ Logo heqingyu的博客

博客

洛谷P3366 题解

2017-10-12 12:47:46 By heqingyu

用kruskal(prim不会。。。)。。

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

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

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

include

include

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;

}

评论

暂无评论