[模板] 最小生成树

克鲁斯卡尔
很好的一个处理方式是 间接排序

也就是通过在另一个数组排序号,保留原始数据。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 200000

using namespace std;

int m,n,ans;

int u[MAXN],v[MAXN],w[MAXN],id[MAXN];

int fa[MAXN];
int fnd(int x){
    if(x==fa[x]) return x;
    return fa[x]=fnd(fa[x]);
}
inline void cat(int x,int y){
//  x=fnd(x);y=fnd(y);
//  if(y!=x) fa[y]=x;
    fa[y]=x;
}

bool cmp(const int x,const int y){
    return w[x]<w[y];
}

void kls(){
    int t=0;
    for(int i=1;i<=m;i++){
        int d=id[i];
        int x=fnd(u[d]),y=fnd(v[d]);
        if(x==y) continue;
        cat(x,y);
        ans+=w[d];
        if(++t>=n-1) break;
    }
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) fa[i]=id[i]=i;
    for(int i=n+1;i<=m;i++) id[i]=i;
    for(int i=1;i<=m;i++){
        cin>>u[i]>>v[i]>>w[i];
    }
    sort(id+1,id+m+1,cmp);
//  for(int i=1;i<=m;i++){
//      int d=id[i];
//      cout<<u[i]<<"->"<<v[i]<<" "<<w[i]<<endl;
//  }
    kls();
    cout<<ans<<endl;
}

正常版本

//Writer:GhostCai && His Yellow Duck

#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN=200000;

int ans,cnt;
int n,m;

struct Edge{
    int x,y,w;
}e[MAXN];
int ecnt=1;
inline void add(int x,int y,int w){
    e[ecnt].w = w;
    e[ecnt].x = x;
    e[ecnt].y= y;
    ecnt++;
}


int fa[MAXN]; 
int fnd(int x){
    return x==fa[x]?x:fa[x]=fnd(fa[x]); 
}
inline void cat(int x,int y){
    fa[y]=x;
}

bool cmp(const Edge &x,const Edge &y){
    return x.w < y.w ;
}

void kls(){
    sort(e+1,e+1+m,cmp);
    for(int i=1;i<=m;i++){
        Edge now=e[i];
        int x=fnd(now.x),y=fnd(now.y);
        if(x==y) continue;
        cat(x,y);
        ans+=now.w;
//      cout<<now.w <<endl;
        if(++cnt>=n-1) break;
    } 
}


int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++){
        int x,y,w;
        cin>>x>>y>>w;
        add(x,y,w);
    }
    kls();
    cout<<ans<<endl;
}
posted @ 2018-01-12 17:42  GhostCai  阅读(102)  评论(0编辑  收藏  举报