hiho一下 第二十九周(最小堆優化Prim)
阿新 • • 發佈:2019-01-06
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;
}