最小生成树poj1258 prim和kruskal

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <stdlib.h>
#include <queue>

using namespace std;

const int maxNum = 101;
int a[maxNum][maxNum];
int N;
int ind;
int father[maxNum];
int rank[maxNum];

class node
{
public:
	int m_id;
	int m_distance;
	node(int id,int distance):m_id(id),m_distance(distance)
	{}
	friend bool operator < (const node &a,const node &b)//从小到大
	{
		return a.m_distance >b.m_distance;
	}
};

void init()
{
	for (int i=0;i<N;++i)
	{
		father[i] = i;
		rank[i] = 0;
	}
}

int findSet(int x)
{
	if(x!=father[x])
		father[x] = findSet(father[x]);
	return father[x];
}

void merge(int i,int j)
{
	int x = findSet(i);
	int y = findSet(j);

	if(x!=y)
	{
		if(rank[x]>rank[y])
			father[y] = x;
		else
		{
			father[x] = y;
			if(rank[x]==rank[y])
				++rank[y];
		}
	}
}

bool judge(int x,int y)
{
	if(findSet(x) == findSet(y))
		return true;
	return false;
}
typedef struct edge 
{
	int value;
	int i;
	int j;
}edge;

edge edges[maxNum*maxNum/2];

int cmp(const void *a,const void *b )//从小到大排序
{
	return ((edge*)a)->value - ((edge*)b)->value;
}


int primQueue()
{
	bool A[maxNum];
	memset(A,0,sizeof(A));

	priority_queue<node> q;
	//q.push(node(0,0));
	A[0] = true;
	for (int i=1;i<N;++i)//算法的简洁,这里应只需要入队一个起点,其距离为0
	{
		q.push(node(i,a[0][i]));
	}
	int sum = 0;
	while (!q.empty())
	{
		node nd = q.top();
		q.pop();
		if(A[nd.m_id])//只要是这个点出队过,以后在出队这个点,就不处理
			continue;
		A[nd.m_id] = true;//一旦出队,不在处理
		sum +=nd.m_distance;
		for (int j = 0;j<N;++j)//在邻接矩阵上找点i的相关边,一定要从0-N遍历,即使是无向图!!!不能自作聪明从i+1开始遍历
		{
			if(!A[j])//有些是没有边的,应该在这一步判断
				q.push(node(j,a[nd.m_id][j]));//将邻接点,并且这些邻接点没有出队过,放入队列中,即使已经在队列中了
		}


	}

	return sum;

}

int Kruskal()
{
	qsort(edges,ind,sizeof(edge),cmp);
	init();
	int sum = 0;
	for (int i=0;i<ind;++i)
	{
		if(findSet(edges[i].i)!=findSet(edges[i].j))
		{
			sum +=edges[i].value;
			merge(edges[i].i,edges[i].j);
		}
	}
	return sum;
}
int main()
{
	while (scanf("%d",&N)!=EOF)
	{
		ind = 0;
		for (int i=0;i<N;++i)
		{
			for (int j=0;j<N;++j)
			{
				scanf("%d",&a[i][j]);
				if(j>i) //for Kruskal
				{
					edges[ind].i = i;
					edges[ind].j = j;
					edges[ind].value = a[i][j];
					++ind;
				}
				
			}
		}
		cout<<primQueue()<<endl;
		
		//cout<<Kruskal()<<endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值