最小生成树poj1258 prim和kruskal

来源:互联网 发布:139邮箱exchange 端口 编辑:程序博客网 时间:2024/05/18 00:38
#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;}

原创粉丝点击