最小生成树的板子--Prim

 废话不说直接上板子

PS.打注释打了5分钟。。。。

#include<iostream>
#include<cstdio>
#define M 100
#define N 50
int d[N+1];
struct E {
	int next,w,to;
} e[(M<<1)+1];
void adde(int a,int b,int w,int num) {
//详见http://blog.csdn.net/qq_21436421/article/details/53159093
	e[num].next=d[a];
	e[num].to=b;
	e[num].w=w;
	d[a]=num;
}
int father[N+1];
//并查集存点是否相连
int vis[N+1];
//代表已被染色的点
int zx(int num) {
	if(num==father[num])return num;
	else return father[num]=zx(father[num]);
}//并查集算祖先
void add(int a,int b) {
	father[zx(a)]=father[zx(b)];
}//并查集合并两点
int main() {
	int n,m;
	scanf("%d%d",&n,&m);
	int dt1,dt2,w;
	for(int i=1; i<=m; ++i) {
		scanf("%d%d%d",&dt1,&dt2,&w);
		adde(dt1,dt2,w,(i<<1)-1);
		adde(dt2,dt1,w,i<<1);
	}
	for(int i=1; i<=n; i++)father[i]=i;//并查集初始化
	vis[1]=1;//初始化,染色点1(染哪个点都可以的。。。)
	e[0].w=233333333;//初始化,由于mine初始值不好找,先设为0,方便更新
	int ans=0;
	for(int i=1; i<n; i++) {
		int mine=0,minj;
		for(int j=1; j<=i; j++)
		//枚举已被染色的点
			for(int k=d[vis[j]]; k; k=e[k].next)
			//枚举:在 vis [j] 和 e[k].to 中连一条边
				if( e[ k ]. w < e [ mine ]. w && zx( vis[ j ] ) != zx( e[k].to ) ) mine=k,minj=j;
	//最终在vis[minj]和e[mine].to连边
		ans+=e[mine].w;
		e[mine].w=233333333;//将此边删去
		add(vis[minj],e[mine].to);//合并这两点所在集合
		vis[i+1]=e[mine].to;//染色这一个点
	}
	printf("%d",ans);
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值