程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 最小生成樹Kruskal算法實現C++實現

最小生成樹Kruskal算法實現C++實現

編輯:C++入門知識

 

// Kruskal算法實現.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include<iostream>

#define MAX 100

typedef  int WeiType;

using namespace std;

//

struct Edge

{

 int no;   //邊的序號

 int x;    //端點1序號

 int y;    // 端點2序號

 WeiType weight;   //權值

 bool selected; //是否被選擇

};

//邊集和

Edge edge[MAX];

//已找到的最小生成樹其中一部分的秩

int rank[MAX];

//已找到的最小生成樹其中一部分的頭結點

//用來判斷一條邊的2個端點是否在一個集合中,即加上這條邊是否會形成回路

int parent[MAX];

//找出每一集合的頭結點

int find_set(int x)

{

 if(x != parent[x] )

  parent[x] = find_set(parent[x]);

 return parent[x];

}

//合並集合

void union_set(int x,int y,WeiType w,WeiType &sum)

{

 if(x==y)

  return;

 if(rank[x]>rank[y])

  parent[y]=x;

 else

 {

  if(rank[x]==rank[y])

   rank[y]++;

  parent[x]=y;

 }

 sum +=w;

}

//依據邊的權值升序快速排序

void fast_sort(Edge *edge,int begin,int end)

{

 if(begin<end)

 {

  int i = begin-1,j=begin;

  edge[0] = edge[end];

  while(j<end)

  {

   if(edge[j].weight<edge[0].weight)

   {

    i++;

    Edge temp1 = edge[i];

    edge[i] = edge[j];

    edge[j] = temp1;

   }

   j++;

  }

  Edge temp2 = edge[end];

  edge[end] = edge[i+1];

  edge[i+1] = temp2;

  fast_sort(edge,begin,i);

  fast_sort(edge,i+2,end);

 }

}

int _tmain(int argc, _TCHAR* argv[])

{

 int cases;

 cout<<"請輸入案例的個數:";

 cin>>cases;

 while(cases--)

 {

  int n;

  //最小生成樹的權值總和

  WeiType sum = 0;

  cout<<"請輸入邊的個數:";

  cin>>n;

  int i;

  //初始化

  char chx,chy;

  WeiType weight;

  for(i=1;i<=n;i++)

  {

   edge[i].no = i;

   cout<<"請輸入第"<<i<<"條邊的二個端點的名稱(小寫字符):";

   cin>>chx>>chy;

   edge[i].x = chx-'a'+1;

   edge[i].y = chy-'a'+1;

   cout<<"這條邊的權值為:";

   cin>>weight;

   edge[i].weight = weight;

   edge[i].selected = false;

   parent[edge[i].x] = edge[i].x;

   parent[edge[i].y] = edge[i].y;

   rank[edge[i].x] = 0;

   rank[edge[i].y] = 0;

  }

  //快排

  fast_sort(edge,1,n);

  for(i=1;i<=n;i++)

  {

   int x,y;

   x = find_set(edge[i].x);

   y = find_set(edge[i].y);

   //判斷即加上這條邊是否會形成回路

   if(x != y )

   {

    //選擇這條邊

    edge[i].selected = true;

    //合並不會形成回路的二個集合

    union_set(x,y,edge[i].weight,sum);

   }

  }

  cout<<"最小生成樹的邊集為:"<<endl;

  for(i=1;i<=n;i++)

  {

   if(edge[i].selected)

   {

    cout<<"序號:"<<edge[i].no<<"  " <<"端點1:"<<(char)(edge[i].x+'a'-1)<<",端點2:"<<(char)(edge[i].y+'a'-1)<<endl;

   }

  }

  cout<<"最小生成樹的權值為:"<<sum<<endl;

 }

 system("pause");

 return 0;

}

-------------------------------------------程序測試-------------------------------------------

\               

 

                      

請輸入案例的個數:1

請輸入邊的個數:14

請輸入第1條邊的二個端點的名稱(小寫字符):a b

這條邊的權值為:4

請輸入第2條邊的二個端點的名稱(小寫字符):a h

這條邊的權值為:8

請輸入第3條邊的二個端點的名稱(小寫字符):b c

這條邊的權值為:8

請輸入第4條邊的二個端點的名稱(小寫字符):b h

這條邊的權值為:11

請輸入第5條邊的二個端點的名稱(小寫字符):c d

這條邊的權值為:7

請輸入第6條邊的二個端點的名稱(小寫字符):c f

這條邊的權值為:4

請輸入第7條邊的二個端點的名稱(小寫字符):c i

這條邊的權值為:2

請輸入第8條邊的二個端點的名稱(小寫字符):d e

這條邊的權值為:9

請輸入第9條邊的二個端點的名稱(小寫字符):d f

這條邊的權值為:14

請輸入第10條邊的二個端點的名稱(小寫字符):e f

這條邊的權值為:10

請輸入第11條邊的二個端點的名稱(小寫字符):f g

這條邊的權值為:2

請輸入第12條邊的二個端點的名稱(小寫字符):g h

這條邊的權值為:1

請輸入第13條邊的二個端點的名稱(小寫字符):g i

這條邊的權值為:6

請輸入第14條邊的二個端點的名稱(小寫字符):h i

這條邊的權值為:7

最小生成樹的邊集為:

序號:12  端點1:g,端點2:h

序號:11  端點1:f,端點2:g

序號:7  端點1:c,端點2:i

序號:1  端點1:a,端點2:b

序號:6  端點1:c,端點2:f

序號:5  端點1:c,端點2:d

序號:3  端點1:b,端點2:c

序號:8  端點1:d,端點2:e

最小生成樹的權值為:37

請按任意鍵繼續. . .

 

 

作者 heyongluoyao8

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved