最小生成树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;
}

你可能感兴趣的:(struct,Class,include,merge,distance)