Kruskal算法优先级队列版 算法基础篇(五)

View Code
  1 // Kruskal算法.cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <queue>
  6 #include <string>
  7 #include <iostream>
  8 using namespace std;
  9 #define Infinity 1000
 10 #define Max 20
 11 typedef int ElemType;
 12 typedef unsigned int EdgeType;
 13 typedef int DisjSet;
 14 typedef int SetType;
 15 struct Edge
 16 {
 17     ElemType From;
 18     ElemType To;
 19     EdgeType Weight;
 20     friend bool operator> (Edge e1,Edge e2)
 21     {
 22         return e1.Weight>e2.Weight;
 23     }
 24 };
 25 
 26 
 27 struct Graphic  //图结构
 28 {
 29     int Arc;
 30     int Vex;
 31     Edge EdgeNode[Max];//边数组
 32 //    ElemType VexNode[Max];
 33     DisjSet S[Max];     //不相交集合数组
 34 
 35 };
 36 typedef struct Graphic* Graph;
 37 
 38 priority_queue<Edge,vector<Edge>,greater<Edge> > EQ; //优先级队列
 39 
 40  void SetUnion(DisjSet S[],SetType Root1,SetType Root2)      //不相交集合的合并
 41  {
 42      S[Root2]=Root1;
 43  }
 44 
 45  SetType  Find(ElemType X,DisjSet S[])  //不相交集合的find算法 这里我们采用算法导论的不相交集合find层层上溯
 46  {
 47      if(S[X]!=X)
 48           S[X]=Find(S[X],S);
 49      
 50          return S[X];
 51 
 52  }
 53 
 54 void ReadGraph(Graph G) //读图函数
 55 {
 56     int i;
 57     for( i=0;i<Max;i++)
 58         G->EdgeNode[i].Weight=Infinity;
 59      printf("请输入点数和边数: ");
 60      scanf("%d%d",&(G->Vex),&(G->Arc));
 61      for( i=0;i<Max;i++)
 62      {
 63          if(i<G->Vex)
 64              G->S[i]=i;
 65          else
 66              G->S[i]=Infinity;
 67      }
 68      for( i=0;i<G->Arc;i++)
 69       {
 70           printf("请输入第%d条边的起点终点和权值:",i+1);
 71           scanf("%d%d%u",&(G->EdgeNode[i].From),&(G->EdgeNode[i].To),&(G->EdgeNode[i].Weight));
 72           EQ.push(G->EdgeNode[i]) ;
 73       }
 74 
 75 }
 76 
 77 
 78 void Kruskal(Graph G)
 79 {
 80     ElemType U,V;
 81     Edge e;
 82     SetType Uset,Vset;
 83     int EdgeAccepted=0;
 84     while(EdgeAccepted<G->Vex-1) 
 85     {
 86         e=EQ.top();                  //弹出最小边
 87         printf("e=%d\n",e.Weight);
 88         EQ.pop();                         
 89         U=e.From;                       
 90         V=e.To;
 91         Uset=Find(U,G->S);             //查找最小边的起点
 92         Vset=Find(V,G->S);             //查找最小边的终点
 93         if(Uset!=Vset)                //不相交集合的合并
 94         {
 95             EdgeAccepted++;
 96             SetUnion(G->S,Uset,Vset);
 97         }
 98     }
 99     for(int i=0;i<G->Vex;i++)
100         printf("G->S[%d]=%d \n",i,G->S[i]);
101 }
102 
103 
104 
105 
106 int _tmain(int argc, _TCHAR* argv[])
107 {
108     Graph G=(Graph)malloc(sizeof(struct Graphic));
109     ReadGraph(G);
110     Kruskal(G);
111 
112     return 0;
113 }
原文地址:https://www.cnblogs.com/cslave/p/2549771.html