图论 || Prim(最小生成树)

Prim:假设有一棵只包含一个顶点的树T,贪心地选取T和其他顶点之间相连的最小权值的边,并把它加入T中,不断进行此操作直到所有点都已加入,就可以得到最小生成树

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<vector>
#define MAX 100000000
using namespace std;
int n;
int a[105][105];
struct edge{
	int v1;
	int v2;
	int w;//边的权值 
	int next;//左端点和这条边一样是v1的另外一条边的编号,若没有则为-1 
};
edge e[10050];
int head[105];//head[x]中存放端点为x的某一条边的编号 
bool f[105];//表示某个点是否已经使用过 
int ans;
void inserte(int k,int v1,int v2,int w){
	e[k].v1=v1;
	e[k].v2=v2;
	e[k].w=w;
	e[k].next=head[v1];
	head[v1]=k;
}//k为边的编号 
void prim(int sp){
	vector<int>b;
	b.insert(b.begin(),sp);
	f[sp]=1;
	//将起点sp加入集合中 
	while(b.size()<n){
		int min=MAX;
		int minv;
		for(int i=0;i<b.size();i++){
			for(int j=head[b[i]];j!=-1;j=e[j].next){
				if(min>e[j].w&&f[e[j].v2]==0){
					min=e[j].w;
					minv=e[j].v2;
				}
				//找到与集合内每个点相连的所有边中权值最小的边及这条边所连的点(未在集合中的点) 
			}
		}
		f[minv]=1;
		ans+=min;
		b.push_back(minv);//将找到的点加入集合 
	}
} 
int main(){
	while(cin>>n){
		
		if(n==0)break;
		ans=0;
		int k=0;
		int q;
		char c;
		for(int i=0;i<n;i++){
			head[i]=-1;
			f[i]=0;
		}
		for(int i=0;i<n-1;i++){			
			cin>>c;
			cin>>q;
			for(int j=0;j<q;j++){
				cin>>c;
				cin>>a[i][j];
				inserte(k,i,(c-'A'),a[i][j]);k++;
				inserte(k,(c-'A'),i,a[i][j]);k++;
				//无向图要记得插入两条边!!!
			}
		}
		prim(0);
		cout<<ans<<endl;
	}
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bekote

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值