最小生成树-prim算法模板

题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz

输入输出格式

输入格式:

第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)

接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi

输出格式:

输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz

输入输出样例

输入样例#1: 复制
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
输出样例#1: 复制
7

说明

时空限制:1000ms,128M

数据规模:

对于20%的数据:N<=5,M<=20

对于40%的数据:N<=50,M<=2500

对于70%的数据:N<=500,M<=10000

对于100%的数据:N<=5000,M<=200000

#include <bits/stdc++.h>
#define MAXV 5005
#define INF 0x3fffffff
using namespace std;
struct Node
{
    int v ,w;
    Node(int _v ,int _w) : v(_v) ,w(_w) {}
};
vector<Node> G[MAXV];
int n ,m ,u ,v ,w;
int d[MAXV];
bool vis[MAXV];
int prim();
int main()
{
    scanf("%d%d" ,&n ,&m);
    for(int i=1 ;i<=m ;i++) {
        scanf("%d%d%d" ,&u ,&v ,&w);
        G[u].push_back(Node(v ,w));
        G[v].push_back(Node(u ,w));
    }
    int Ans=prim();
    if(Ans==-1) printf("orz");
    else printf("%d" ,Ans);
    return 0;
}
int prim()
{
    fill(d ,d+MAXV ,INF);
    d[1]=0;
    int ans=0;
    for(int i=1 ;i<=n ;i++) {
        int u=-1 ,minn=INF;
        for(int j=1 ;j<=n ;j++)
            if(!vis[j] && d[j]<minn) {
                u=j;
                minn=d[j];
            }
        if(u==-1)   return -1;
        vis[u]=true;
        ans+=d[u];
        for(int j=0 ;j<G[u].size() ;j++) {
            int v=G[u][j].v;
            if(!vis[v] && G[u][j].w<d[v])
                d[v]=G[u][j].w;
        }
    }
    return ans;
}

  

原文地址:https://www.cnblogs.com/Roni-i/p/8674899.html