模板:最小生成树

https://www.luogu.org/problemnew/show/P3366

Kruskal算法

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 struct Edge{
 6     int u, v, w;
 7 }edge[200005];
 8 int f[5005], n, m, ans, eu, ev, cnt;
 9 inline bool cmp(Edge a,Edge b){ 
10     return a.w<b.w; 
11 }
12 inline int find(int x){
13     while(x!=f[x]) x=f[x]=f[f[x]];
14     return x;
15 }
16 int main(){
17     scanf("%d%d",&n,&m);
18     for(int i=1; i<=n; i++) f[i]=i;
19     for(int i=0; i<m; i++)
20         scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
21     sort(edge, edge+m, cmp);
22     for(int i=0; i<m; i++){
23         eu=find(edge[i].u);
24         ev=find(edge[i].v);
25         if(eu==ev) continue;
26         ans+=edge[i].w;
27         f[ev]=eu; 
28         cnt++;
29         if(cnt==n-1) break;
30     }
31     printf("%d",ans);
32     return 0;
33 }

Prim

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
priority_queue <pair <int,int>,vector<pair <int,int> >,greater<pair <int,int> > > q;
int k, n, m, cnt, sum, a, b, c, head[5005], dis[5005], vis[5005];
struct Edge{
    int v, w, next;
}e[400005];

void add(int u,int v,int w){
    e[++k].v=v;
    e[k].w=w;
    e[k].next=head[u];
    head[u]=k;
}

void prim(){
    dis[1]=0;
    q.push(make_pair(0,1));
    while(!q.empty() && cnt<n){
        int d=q.top().first, u=q.top().second;
        q.pop();
        if(vis[u]) continue;
        cnt++;
        sum+=d;
        vis[u]=1;
        for(int i=head[u]; i!=-1; i=e[i].next)
            if(e[i].w<dis[e[i].v])
                dis[e[i].v]=e[i].w,q.push(make_pair(dis[e[i].v],e[i].v));
    }
}

int main(){
    memset(dis,127,sizeof(dis));
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
        add(b,a,c);
    }
    prim();
    if (cnt==n)printf("%d",sum);
    else printf("orz");
}

猜你喜欢

转载自www.cnblogs.com/Aze-qwq/p/9337735.html