P3366 【模板】最小生成树

链接:https://www.luogu.com.cn/problem/P3366
模板题:
kruskal代码:
核心是对边的排序,遍历,选择。

#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int N = 5e3 + 5, M = 2e5 + 1;
struct Edge { ll u, v, w; Edge() {}; }edge[M];
bool cmp(Edge a, Edge b) { return a.w < b.w; }
ll s[N];
ll find_set(ll x)
{
	if (x != s[x])s[x] = find_set(s[x]);
	return s[x];
}
ll n, m;
void kruskal()
{
	sort(edge + 1, edge + m + 1, cmp);
	for (int i = 1; i <= n; i++)s[i] = i;
	ll ans = 0, cnt = 0;
	for (int i = 1; i <= m; i++)
	{
		if (cnt == n - 1)break;
		ll e1 = find_set(edge[i].u);
		ll e2 = find_set(edge[i].v);
		if (e1 == e2)continue;
		else
		{
			s[e1] = e2;
			ans += edge[i].w;
			cnt++;
		}
	}
	if (cnt == n - 1)cout << ans;
	else cout << "orz";
}
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}
	kruskal();
	return 0;
}

prim代码:
核心思路优先队列找点

#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int N = 5e3 + 5, M = 2e5 + 1;
struct edge
{
	ll to, w;
	edge(ll a, ll b) { to = a; w = b;}
};
vector<edge>G[M];
struct node
{
	ll id, dis;//id:点,dis:边
	node(ll a, ll b) { id = a, dis = b; }
	bool operator <(const node& u)const {return dis > u.dis;}
};
ll n,m;
bool done[N];
void prim()
{
	ll s = 1;//s:any point to begin
	memset(done, 0, sizeof(done));
	priority_queue<node>q;
	q.push(node(s, 0));
	ll ans = 0,cnt=0;
	while (!q.empty())
	{
		node u = q.top(); q.pop();
		if (done[u.id])continue;
		done[u.id] = 1;
		ans += u.dis;
		cnt++;
		for (edge i : G[u.id])
		{
			if (done[i.to])continue;
			q.push(node(i.to, i.w));//下一个距离
		}
	}
	if (cnt == n)cout << ans;//cnt:选取的点的个数
	else cout << "orz";
}
int main()
{
	ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		ll u, v, w; cin >> u >> v >> w;
		G[u].push_back(edge(v, w)), G[v].push_back(edge(u, w));
	}
	prim();
	return 0;
}

posted on 2024-05-15 21:42  WHUStar  阅读(2)  评论(0编辑  收藏  举报