1. 程式人生 > >hiho一下 第二十九周(最小堆優化Prim)

hiho一下 第二十九周(最小堆優化Prim)

AC程式碼:

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 5;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
#define LL long long

struct Edge{
    int v, w, nxt;
}edge[maxn * 20], Heap[maxn * 20];

int tot, head[maxn << 1];
int hlength, n, m;

void init(){
    hlength =
tot = 0; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int w) { edge[tot].v = v; edge[tot].w = w; edge[tot].nxt = head[u]; head[u] = tot ++; edge[tot].v = u; edge[tot].w = w; edge[tot].nxt = head[v]; head[v] = tot ++; } void down(int p) { int
q = p * 2; Edge a = Heap[p]; while(q <= hlength) { if(q < hlength && Heap[q].w > Heap[q + 1].w) q ++; if(Heap[q].w >= a.w) break; else { Heap[p] = Heap[q]; p = q; q = p * 2; } } Heap[p] = a; } void
up(int p) { int q = p/2; Edge a = Heap[p]; while(q >= 1 && a.w < Heap[q].w) { Heap[p] = Heap[q]; p = q; q = p/2; } Heap[p] = a; } void insert(Edge a) { Heap[++ hlength] = a; up(hlength); } Edge getMin() { Edge r = Heap[1]; Heap[1] = Heap[hlength --]; down(1); return r; } int ans = 0; int dis[maxn], vis[maxn]; void Prim() { memset(dis, INF, sizeof(dis)); memset(vis, 0, sizeof(vis)); dis[1] = 0; insert({1, 0, -1}); while(hlength) { Edge t = getMin(); if(vis[t.v]) continue; ans += t.w; vis[t.v] = 1; for (int i = head[t.v]; i + 1; i = edge[i].nxt) { if(!vis[edge[i].v] && dis[edge[i].v] > edge[i].w) { dis[edge[i].v] = edge[i].w; insert({edge[i].v, edge[i].w, -1}); } } } } int main() { init(); scanf("%d %d", &n, &m); for (int i = 0; i < m; i ++) { int u, v, w; scanf("%d %d %d", &u, &v, &w); addEdge(u, v, w); } Prim(); cout << ans << endl; return 0; }