以洛谷P3366为例
Prim算法板子
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1e9;
const int maxn = 5e3 + 5; //点的数据范围
const int maxm = 2e5 + 5; //边的数据范围
struct node{
int to;
int weight;
int next;
}edge[maxm << 1]; //无向图需要两倍的存储空间
int head[maxn];
int dist[maxn]; //表示当前点与相连的已访问过的点最小的权重
bool vis[maxn]; //标记当前点有没有被访问过
int n, m; //点数,边数
int cnt = 0;//链式前向星的边的条数
void add(int u, int v, int weight)
{
edge[cnt].to = v;
edge[cnt].weight = weight;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void init()
{
fill(head + 1, head + n + 1, -1); //初始化成-1
fill(vis + 1, vis + n + 1, false); //初始化成未访问
}
void slove()
{
scanf("%d%d", &n, &m);
init();
while(m--){
int u, v, weight;
scanf("%d%d%d", &u, &v, &weight);
add(u, v, weight);
add(v, u, weight);
}
}
int prim()
{
fill(dist + 2, dist + n + 1, MAX);
for(int i = head[1]; ~i; i = edge[i].next){
int v = edge[i].to;
dist[v] = min(dist[v], edge[i].weight);
}
int cur = 1; //当前点
int ans = 0; //当前树的总权重
int tot = 0; //当前加入生成树的边数
while(++tot < n){//
//找与刚选的的结点相连,权重最小的边
vis[cur] = true;//当前点标记成已访问
int minn = MAX;
for(int i = 1; i <= n; i++){
if(!vis[i] && dist[i] < minn){
minn = dist[i];
cur = i;
}
}
ans += minn;//加入当前选中的边的权重
//更新选中点的边权重
for(int i = head[cur]; ~i; i = edge[i].next){
int v = edge[i].to;
if(!vis[v] && edge[i].weight < dist[v]){
dist[v] = edge[i].weight;
}
}
}
return ans;
}
int main()
{
slove();
printf("%d\n", prim() );
return 0;
}
Kruskal算法板子
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e3 + 10;
const int maxm = 2e5 + 10;
int n, m;
int father[maxn];
struct Edge
{
int u, v, weight;
} edge[maxm];
int find(int x)
{
while(x != father[x])
x = father[x] = father[father[x]];
return x;
}
bool cmp(const Edge a, const Edge b)
{
return a.weight < b.weight;
}
int kruskal()
{
sort(edge + 1, edge + m + 1, cmp);
int tot = 0;
int ans = 0;
for(int i = 1; i <= m; i++){
int au, av;
au = find(edge[i].u);
av = find(edge[i].v);
if(au == av) //连通
{
continue;
}
tot++;
ans += edge[i].weight;
father[av] = au;//连上去
if(tot == n - 1)break;
}
return ans;
}
void slove()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
edge[i].u = u;
edge[i].v = v;
edge[i].weight = w;
}
for(int i = 1; i <= n; i++)
{
father[i] = i;
}
}
int main()
{
slove();
printf("%d",kruskal());
return 0;
}