模板-最小生成树

Prim

#include <cstdio>
#include <algorithm>
#include <string>
#include <queue>
#define MAXN 200005

struct Node {
    int u,dis;
    inline bool operator < (const Node& node) const {
        return dis > node.dis;
    }
};

std::priority_queue < Node > q;

struct edge {
    int u,v,w,next;
} G[MAXN<<1];

int head[MAXN],vis[MAXN],dis[MAXN];
int N,M,tot = 0;

inline void add(int u,int v,int w) {
    G[++tot].v = v; G[tot].w = w; G[tot].next = head[u]; head[u] = tot;
}

int main() {

    scanf("%d%d",&N,&M);
    for(int i=1;i<=M;++i) {
        int u,v,w; scanf("%d%d%d",&u,&v,&w);
        add(u,v,w); add(v,u,w);
    }

    for(int i=1;i<=N;++i) dis[i] = 2147483647;
    dis[1] = 0; q.push( (Node){1,0} );
    int ans = 0;

    while(!q.empty()) {
        
        int u = q.top().u;  q.pop();
        if(vis[u]) continue; vis[u] = 1;

        ans += dis[u];

        for(int i=head[u];i;i=G[i].next) {
            int v = G[i].v; int w = G[i].w;
            if(dis[v]>w) q.push( (Node){v,dis[v]=w} );
        }
    }

    int cnt = 0;
    for(int i=1;i<=N;++i) cnt += vis[i];
    if(cnt==N) printf("%d",ans);
    else puts("orz");
    return 0;
}

Kruscal

#include <cstdio>
#include <algorithm>

using namespace std;
const int maxn=200005;

int fa[5005],u[maxn],v[maxn],w[maxn];

inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
inline void merge(int x,int y){
    int xx=find(x),yy=find(y);
    if(xx!=yy)fa[xx]=yy;
}

inline void qs(int l,int r){
    int i=l,j=r,s=w[(l+r)/2];
    do{
        while(w[i]<s)i++;
        while(w[j]>s)j--;
        if(i<=j){
            swap(u[i],u[j]);
            swap(v[i],v[j]);
            swap(w[i],w[j]);
            i++;
            j--;
        }
    }while(i<j);
    if(i<r)qs(i,r);
    if(l<j)qs(l,j);
}

int main() {
    int n,m;
    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\n",&u[i],&v[i],&w[i]);
    qs(1,m);
    int cnt=0,ans=0;
    for(int i=1;i<=m;i++){
        if(find(u[i])!=find(v[i])){
            merge(u[i],v[i]);
            ans+=w[i];
            cnt++;
        }
        if(cnt==n-1)break;
    }
    printf("%d\n",ans);
    return 0;
}
posted @ 2018-03-04 17:04  Neworld1111  阅读(104)  评论(0)    收藏  举报