1. 程式人生 > >備戰NOIP——模板複習19

備戰NOIP——模板複習19

這裡只有模板,並不作講解,僅為路過的各位做一個參考以及用做自己複習的資料,轉載註明出處。

最小生成樹

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;
}

Kruskal