最小生成树——kruskal

来源:互联网 发布:达内seo百度云 编辑:程序博客网 时间:2024/05/24 06:33
#include<iostream>#include<algorithm>using namespace std;struct e{    int s,t,v;};int f[1000],n,m,cost=0;e g[1000];bool c(e a,e b){    if (a.v==b.v){        if (a.s==b.s){            return a.t<b.t;        }        else return a.s<b.s;    }    else return a.v<b.v;}void qs(int l,int r){    int i=l,j=r;    e x=g[(l+r)/2];    do{        while (c(g[i],x)) i++;        while (c(x,g[j])) j--;        if (i<=j){            swap(g[i],g[j]);            i++;j--;        }    }while (i<=j);    if (l<j) qs(l,j);    if (i<r) qs(i,r);}void init(){    for (int i=1;i<=n;i++) f[i]=i;}int getf(int a){    if (f[a]!=a) f[a]=getf(f[a]);    return f[a];}void uni(int x,int y){    int xx=getf(x),yy=getf(y);    if (xx!=yy){        f[xx]=yy;    }}bool tr(){    int ans=0;    for (int i=1;i<=n;i++){        if (f[i]==i) ans++;    }    return ans>1;}void solve(){    int l=1;    while (tr()){        if (getf(g[l].s)!=getf(g[l].t)){            cost+=g[l].v;            uni(g[l].s,g[l].t);        }        l++;    }}int main(){    cin>>n>>m;    init();    for (int i=1;i<=m;i++){        int a,b,c;        cin>>a>>b>>c;        g[i].s=min(a,b);        g[i].t=max(a,b);        g[i].v=c;    }    qs(1,m);    solve();    cout<<cost<<endl;}
基本思想就是并查集的思想,按照并查集的基本思路写,就可以了,取出来n-1条边。
0 0
原创粉丝点击