0
点赞
收藏
分享

微信扫一扫

堆优化的prime算法

殇感故事 2022-02-04 阅读 71
算法

Prim和Dijkstra的贪心思想是一样的并且也可以用类似的方法实现
代码如下

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
struct Edge
{
    int from,to,dist;
};
int n,m;
vector<Edge>edges;
vector<int>G[maxn];
void add(int from,int to,int dist)
{
    edges.push_back({from,to,dist});
    int m=edges.size();
    G[from].push_back(m-1);
}

struct HeapNode
{
    int d,u;
    bool operator <(const HeapNode &rhs)const{
            return d>rhs.d;
    }
};
int cnt=0,sum=0;
int dis[maxn];
bool vis[maxn];
priority_queue<HeapNode>Q;
void prime()
{
        dis[1]=0;
        Q.push({0,1});
        while(!Q.empty()&&cnt<n)
        {
            HeapNode temp=Q.top();
            Q.pop();
            int u=temp.u;
            int d=temp.d;
            if(vis[u])
                continue;
            vis[u]=true;
            cnt++;//统计连通块里的点的数量
            sum+=d;
            for(int i=0;i<G[u].size();i++)
            {
                Edge e=edges[G[u][i]];
                if(e.dist<dis[e.to])//松弛
                {
                    dis[e.to]=e.dist;
                    Q.push({dis[e.to],e.to});
                }
            }
        }
}


int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    memset(dis,inf,sizeof(dis));
    memset(vis,false,sizeof(vis));
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
    }
    prime();
    if(cnt==n)//看连通块里的点是否等于题目给的点,如果等于则为最小生成树
        cout<<sum;
    else
        cout<<"orz";


}

举报

相关推荐

0 条评论