求最小生成树kruskal还是prim--备战蓝桥杯版h

解决的主要是什么问题呢,我感觉其实就是连接各点所需要的最小代价之类的问题

什么时候用kruskal/prim

prim算法(二维数组实现)

其实就是点为先,以点去扩展,每次选择的是这个点扩展出边的最小值

cpp 复制代码
int prim()
{
	memset(dist,0x3f,sizeof dist);
	dist[1]=0;
	
	int res=0;
	for(int i=0;i<n;i++)//一共n个点 
	{
		int t=-1;
		//先找到最小的dist的点
		for(int j=1;j<=n;j++)
		{
			if(!st[j]&&(t==-1||dist[j]<dist[t]))
			{
				t=j;
			}
		 } 
		st[t]=true;
		
		if(i)res+=dist[t];
		//更新其他点 
		for(int j=1;j<=n;j++)
		{
			dist[j]=min(dist[j],g[t][j]);
		}
	}
	return res;
}

练习1

858. Prim算法求最小生成树 - AcWing题库

cpp 复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=510,INF=0x3f3f3f3f;
int n,m;
int dist[N];
bool st[N];
int g[N][N];

int prime()
{
	memset(dist,0x3f,sizeof dist);
	dist[1]=0;
	
	int res=0;
	for(int i=0;i<n;i++)
	{
		int t=-1;
		for(int j=1;j<=n;j++)
		{
			if(!st[j]&&(t==-1||dist[j]<dist[t]))
			{
				t=j;
			}
		}
		if(i&&dist[t]==INF)return INF;
		if(i)res+=dist[t];
		st[t]=true;
		 
		for(int j=1;j<=n;j++)
		{
			dist[j]=min(dist[j],g[t][j]);
		}
	}
	return res;
} 


int main()
{
	cin>>n>>m;
	memset(g,0x3f,sizeof g);
	while(m--)
	{
		int a,b,c;
		cin>>a>>b>>c;
		g[a][b]=g[b][a]=min(g[a][b],c);
	}
	int t=prime();
	if(t==INF)cout<<"impossible"<<endl;
	else cout<<t<<endl;
	return 0;
}

练习2

P1265 公路修建 - 洛谷

cpp 复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 5010;
const double INF = 1e18;
int n;
struct node{
    int x, y;
} q[N];
double dist[N];
bool st[N];

double distance(int x1, int y1, int x2, int y2)
{
    double dx = x1 - x2;
    double dy = y1 - y2;
    return sqrt(dx*dx + dy*dy);
}

double prim()
{
    for(int i = 1; i <= n; i++) dist[i] = INF;
    dist[1] = 0;
    double res = 0;
    
    for(int i = 1; i <= n; i++)
    {
        int t = -1;
        for(int j = 1; j <= n; j++)
        {
            if(!st[j] && (t == -1 || dist[j] < dist[t]))
                t = j;
        }
        
        st[t] = true;
        res += dist[t];
        
        for(int j = 1; j <= n; j++)
        {
            if(!st[j])
            {
                double d = distance(q[t].x, q[t].y, q[j].x, q[j].y);
                if(d < dist[j])
                    dist[j] = d;
            }
        }
    }
    return res;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> q[i].x >> q[i].y;
    }
    
    double res = prim();
    printf("%.2f\n", res);
    
    return 0;
}

练习3

P1340 [IOI 2003] 兽径管理 - 洛谷

cpp 复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=210,INF=0x3f3f3f3f;

int n,w;
int g[N][N];
int dist[N];
bool st[N];

int prime()
{
	memset(dist,0x3f,sizeof dist);
	memset(st,0,sizeof st);
	dist[1]=0;
	int res=0;
	for(int i=0;i<n;i++)
	{
		int t=-1;
		for(int j=1;j<=n;j++)
		{
			if(!st[j]&&(t==-1||dist[j]<dist[t]))
			{
				t=j;
			}
		}
		if(i&&dist[t]==INF)return -1;
		if(i)res+=dist[t];
		st[t]=true; 
		for(int j=1;j<=n;j++)
		{
			dist[j]=min(dist[j],g[t][j]);
		 } 
	}
	return res;
} 

int main()
{
	cin>>n>>w;
	memset(g,0x3f,sizeof g);
	for(int i=1;i<=w;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		g[a][b] = g[b][a] = min(g[a][b], c);
		int res=prime();
		cout<<res<<endl;
	}
	return 0;
}

kruskal算法(大部分题目)

先找最小边依次将最小边加入

cpp 复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010;
const int M=200010;
int p[N];
int n,m;
struct EDGE
{
    int a,b,w;
}edge[M];
//并查集找父节点
int find(int x)
{
    if(p[x]!=x)p[x]=find(p[x]);
    return p[x];
}
//结构体排序函数
bool cmp(EDGE a,EDGE b)
{
    return a.w<b.w;
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int x,y,c;
        cin>>x>>y>>c;
        edge[i].a=x;
        edge[i].b=y;
        edge[i].w=c;
    }
    //按照权重从小到大排序
    sort(edge,edge+m,cmp);
    //并查集初始化
    for(int i=0;i<n;i++)p[i]=i;
    //res是权重,cnt是边的条数
    int res=0,cnt=0;
    //kruskal算法:从最小的边开始画,直到把整个图画通。
    for(int i=0;i<m;i++)
    {
        int a=edge[i].a;
        int b=edge[i].b;
        int w=edge[i].w;
        a=find(a),b=find(b);
        if(a!=b)
        {
            p[a]=b;
            res+=w;
            cnt++;
        }
    }
    if(cnt<n-1)cout<<"impossible"<<endl;
    else cout<<res<<endl;
    return 0;
}

练习题(题单里的题目大部分都ok)

最小生成树专题 - 题单 - 洛谷 | 计算机科学教育新生态

相关推荐
吃好睡好便好8 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
仰泳之鹅9 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
x_yeyue11 小时前
三角形数
笔记·算法·数论·组合数学
念何架构之路12 小时前
Go语言加密算法
数据结构·算法·哈希算法
AI科技星12 小时前
《数学公理体系·第三部·数术几何》(2026 年版)
c语言·开发语言·线性代数·算法·矩阵·量子计算·agi
失去的青春---夕阳下的奔跑12 小时前
560. 和为 K 的子数组
数据结构·算法·leetcode
黎阳之光13 小时前
黎阳之光:以视频孪生重构智慧医院信息化,打造高标项目核心竞争力
大数据·人工智能·物联网·算法·数字孪生
丷丩13 小时前
三级缓存下MVT地图瓦片服务性能优化策略
算法·缓存·性能优化·gis·geoai-up
m0_6294947313 小时前
LeetCode 热题 100-----25.回文链表
数据结构·算法·leetcode·链表
ʚ希希ɞ ྀ15 小时前
单词拆分----dp
算法