#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;
}
最小生成树poj1258 prim和kruskal
最新推荐文章于 2020-08-09 17:13:26 发布