最小生成树问题, Prim算法,Kruskal算法

1.Prim算法
从某个顶点开始,假设v0,设v0在一顶点集合u中, 此时顶点集合u只有一个点v0,选取集合u中的点到与其他点权值最小的一个边, 并将与之相连的点加入集合u, 不断重复此操作, 最后的到一颗最小生成树。

int cost[maxv][maxv]			//cost[u][v]表示u, v两点间权值, 两点无边则取INF
int mincost[maxv]				//保存最小权值
bool used[maxv]					//判断顶点i是否在集合u中
int V;

int prim()
{
	for(int i = 0; i < V; i++)
	{
		mincost[i] = INF;
		used[i] = false;
	}

	mincost[0] = 0;
	int res = 0;

	while(true)
	{
		int v = -1;
		for(int i = 0; i < V; i++)
			if(!used[i] && (v == - 1 || mincost[i] < mincost[v])) v = i;

			if(v == - 1) break;
			used[v] = true;
			res += mincost[v];

		for(int i = 0; i < V; i++)				//所有选出的点更新mincost, 
												//得到点集合与非集合中点的距离。之后再从中又选出最小距离
			mincost[i] = min(mincost[i], cost[v][i]);
	}

}

2.Kruskal

将所有的边按照权值从小到大排序,遍历所有的边,看这两个点是否属于同一个连通分量,如果属于就舍去此边选择下一个较小的边,否则,就输出这条边,并且将这两个点合并成一个连通分量.


struct edge{int u, v, cost;};
bool comp(edge &e1, edge &e2)
{
	return e1.cost < e2.cost;
}

edge es[maxe];
int V, E;
int par[manv]
void init(int n)
{
	for(int i = 0; i < n; i++)
	{
		par[i] = i;
	}
}

void unite(int x, int y)
{
	par[x] = y;
}

int find(int x)
{
	if(par[x] == x) return x;
	return par[x] = find(par[x]);
}

bool same(int x, int y)
{
	return find(x) == find(y);
}

int kruskal()
{
	sort(es, es + E, comp);
	init(V);
	int res = 0;
	for(int i = 0; i < E; i++)
	{
		edge e = es[i];
		if(!same(e.u, e.v))
		{
			unit(e.u, e.v);
			res += e.cost;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值