最小生成树模板

Kruskal算法模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
	int x,y;//树一条边的起点和终点;
	int w;// 边权(边的价值或大小)
}a[110];
int pre[110];//每个点的信息; 并查集所用;
bool cmp(struct node a,struct node b)
{
	return a.w<b.w;
}
int find(int root)// 查找函数(并查集)
{
	if(root!=pre[root]) root=find(pre[root]);
	return pre[root];
}
int main()
{
	int n,i,m;
	while(scanf("%d %d",&n,&m),n)
	{
		memset(pre,0,sizeof(pre));
		int sum=0,num=0;
		for(i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);//输入各个边的起点、终点和权值;
		sort(a+1,a+1+m,cmp);// 对各个边进行排序;
		for(i=1;i<=n;i++) pre[i]=i;
		for(i=1;i<=m;i++)// 从小到大开始枚举测试边;用并查集判断是否构成环; 不构成则加入;
		{
			int f1=find(a[i].x);
			int f2=find(a[i].y);
			if(f1!=f2)
			{
				pre[f1]=f2;
				sum+=a[i].w;//存储最小的边权和;
				num++;
			}
			if(num==n-1) break;// 满足树的性质; 边的条数==点的个数-1;
		}
		if(num==n-1)//判断是否存在;
		printf("%d\n",sum);
		else printf("?\n");
	}
	return 0;
}

Prim 模板

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
 
#define ll long long
 
using namespace std;
 
struct node{
	int to,len;
	node(int x,int y){to=x,len=y;}
	friend bool operator < (node a,node b){
		return a.len>b.len;
	}
};
 
int n,m;
priority_queue<node>q;
int ans=0;
bool vis[1010];
vector<node>v[1010];
 
void link(int x,int y,int z){
	v[x].push_back(node(y,z));
	v[y].push_back(node(x,z));
}
 
int main(){
	scanf("%d%d",&n,&m);
	for(int i=0; i<m; i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		link(x,y,z);
	}
	vis[1]=true;
	for(int i=0; i<v[1].size(); i++)q.push(node(v[1][i].to,v[1][i].len));
	int sum=1;
	while(!q.empty()){
		node t=q.top();
		q.pop();
		if(vis[t.to])continue;
		sum++;
		ans+=t.len;
		vis[t.to]=true;
		if(sum==n)break;
		for(int i=0; i<v[t.to].size(); i++)if(!vis[v[t.to][i].to])q.push(node(v[t.to][i].to,v[t.to][i].len));
	}
	if(sum==n)printf("%d\n",ans);
	else printf("-1\n");
	
	return 0;
}

模板二:
模板题

#include <iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#define MAX 27
//图的规模
#define INF 99999999
//定义无穷大
using namespace std;
int N;
//节点的数目N
//此外,在这里可能会有路径的数目M
int map[MAX][MAX];
//邻接表
int micost[MAX];
//到上一个点的最小路径
int vis[MAX];
//记录该点有没有加入最小生成树中
void Prim()
{
   int i,j,v,Min;
   int ans;
   //最小生成树的总权值
   //1是第一个加入该最小生成树的节点
   for(i=1;i<=N;i++)
   {
    micost[i]=map[1][i];
    vis[i]=0;
   }//初始化节点
   //定义每个节点的micost为1到其他点的距离
   micost[1]=0;
   vis[1]=1;
   //起点的上一个节点没有节点,所以为0
   //定义起点已经加入了最小生成树
   ans=0;
   //初始化最小生成树的权值为零
   //注意在循环里起点不包含进去
   //为了防止错误
   //因为不包含起点所以循环要从i=2开始
   for(i=2;i<=N;i++)
   {
    Min=INF;
    for(j=2;j<=N;j++)
    {
        if(!vis[j]&&Min>micost[j])
            v=j,Min=micost[j];
    }//找micost最小的节点并加入最小生成树
     vis[v]=1;
     if(Min!=INF)
     ans=ans+Min;
     for(j=2;j<=N;j++)
     {
        if(!vis[j]&&micost[j]>map[v][j])
            micost[j]=map[v][j];
     }//更新节点
   }
   cout<<ans<<endl;
}
int main()
{
    int i,j,num,x,y,z;
    char a,b;
    while(cin>>N,N)//输入图的节点数,路径数,(一般情况下)
    {
      for(i=1;i<=N;i++)
        for(j=1;j<=N;j++)
      {
        if(i==j)map[i][j]=0;
        else
            map[i][j]=INF;
      }//初始化邻接表
        for(i=1;i<N;i++)
        {
            cin>>a>>num;
            for(j=1;j<=num;j++){
                cin>>b>>z;
                x=a-64;
                y=b-64;
                map[x][y]=map[y][x]=z;
            }
        }//输入图
        Prim();
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值