1. 程式人生 > >Day7 prim的堆優化

Day7 prim的堆優化

複雜度:O(MlogM) (M為邊數),未優化時複雜度為O(N^2)

首先把1這個點標記為已訪問,把它所連的邊都加到優先佇列裡邊,然後每次從優先佇列頂端拿終點未訪問的邊,把終點標記成已訪問,把終點連的邊放進優先佇列,直到無邊可拿或所有點均訪問過為止。

程式碼:參考別人的程式碼..    https://blog.csdn.net/jhgkjhg_ugtdk77/article/details/47081375

#include<iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
using namespace std;
const int maxn = 1000005;

struct Edge{
    int from,to,len;
    Edge(int x,int y,int l){
        this -> from = x;
        this -> to = y;
        this -> len = l;
    }
    friend bool operator<(Edge a,Edge b){
        return a.len>b.len;
    }
};

priority_queue<Edge> pq;
vector<Edge> graph[maxn];
bool vis[maxn];

int n,m;

int main(){
    scanf("%d%d",&n,&m);
    int x,y,l;
    for(int i=1; i<=m; i++){
        scanf("%d%d%d",&x,&y,&l);
        graph[x].push_back(Edge(x,y,l));
        graph[y].push_back(Edge(y,x,l));
    }

    while(!pq.empty()) pq.pop();
    for(int i=0; i<graph[1].size(); i++){
        pq.push(graph[1][i]);
    }
    vis[1] = true;
    int left = n;
    int ans = 0;
    while((!pq.empty()) && left){
        Edge e = pq.top(); pq.pop();
        if(vis[e.to]) continue;
        ans += e.len;
        left --;
        vis[e.to] = true;
        for(int i=0; i<graph[e.to].size(); i++){
            Edge ee = graph[e.to][i];
            if(vis[ee.to] == false){
                pq.push(ee);
            }
        }
    }
    printf("%d\n",ans);

    return 0;
}