備戰NOIP——模板複習19
阿新 • • 發佈:2019-02-07
這裡只有模板,並不作講解,僅為路過的各位做一個參考以及用做自己複習的資料,轉載註明出處。
最小生成樹
Prim
/*Copyright: Copyright (c) 2018 *Created on 2018-11-05 *Author: 十甫 *Version 1.0 *Title: Prim *Time: inf mins */ #include<cstdio> #include<iostream> #include<cstring> #include<queue> using namespace std; const int maxn = 10005; const int maxm = 10005; int head[maxn]; struct edge { int to, val, next; } data[maxm * 2]; inline void add_edge(int from, int to, int val, int i) { data[i] = (edge) {to, val, head[from]}; head[from] = i; } int n, m; int dis[maxn]; bool vis[maxn]; struct node { int dist, ord; bool operator < (const node cmp) const { return dist > cmp.dist; } }; int Prim(int p) { int ans = 0; memset(dis, 0x3f, sizeof(dis)); memset(vis, false, sizeof(vis)); dis[p] = 0; priority_queue <node> q; q.push((node) {dis[p], p}); for(int i = 1;i <= n;i++) { while(vis[q.top().ord]) q.pop(); node tmp = q.top(); int u = tmp.ord; q.pop(); vis[u] = true; ans += tmp.dist; for(int i = head[u];i;i = data[i].next) { int v = data[i].to, k = data[i].val; if(dis[v] > k) { dis[v] = k; q.push((node) {dis[v], v}); } } } return ans; } int main() { scanf("%d%d", &n, &m); for(int i = 1;i <= m;i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add_edge(a, b, c, i), add_edge(b, a, c, i + m); } printf("%d\n", Prim(1)); return 0; }