最小生成樹

最小生成樹構造

實驗目的

 熟悉最小生成樹的構造算法,掌握最小生成樹的構造過程。

實驗內容與要求

定義1 設T是一個連通且迴路的無向圖,則稱T爲無向樹,簡稱樹。樹中度數爲1的結點稱爲樹葉,度數大於1的結點稱爲分枝點(或內點)。
定義2設G=<V,E>是一個連通的無向圖,若G的某個生成子圖是一棵樹,則稱該樹爲G的生成樹,記爲TG。
定義3假定圖G是具有n個結點的連通圖。對應於G的每一條邊e,指定一個正數C(e),把C(e)稱作邊e的權,(可以是長度、運輸量、費用等)。G的生成樹也具有一個樹權C(T),它是T的所有邊權的和。
定義4 在帶權的圖G的所有生成樹中,樹權最小的那棵生成樹,稱作最小生成樹。
定理1 (Kruskal) 
	設圖G有n個結點,執行如下步驟
	⑴ 選擇權最小的邊e1,置邊數i←1;
	⑵ i=n-1結束,否則轉⑶;
	⑶ 設定已選定e1,e2,,…,ei,在G中選取不同於e1,e2,,…,ei的邊ei+1,使{e1,e2,,…,ei,ei+1}無迴路且ei+1是滿足此條件的權最小的邊。
	⑷ i←i+1,轉⑵。
本實驗要求從鍵盤輸入一個賦權圖(邊權,以矩陣形式輸入),求出對應的最小生成樹。用C語言或MATLAB實現。

源程序

#include<iostream>
using namespace std;
int n,**a;
bool **b,**c,d=0;
bool bestTree(int);
void Closure();
int main()
{
 int i;
 cout<<"請輸入帶權圖結點個數:";
 cin>>n;
 a=new int*[n];
 b=new bool*[n];
 c=new bool*[n];
 for(i=0;i<n;i++)
 {
  a[i]=new int[n];
  b[i]=new bool[n];
  c[i]=new bool[n];
 }
 cout<<"請輸入帶權圖:"<<endl;
 for(i=0;i<n;i++)
  for(int j=0;j<n;j++)
  {
   b[i][j]=0;
   c[i][j]=0;
   cin>>a[i][j];
  }
 bestTree(n-1); 
 for(i=0;i<n;i++)
  for(int j=i;j<n;j++)
   if(b[i][j]==1)
    b[j][i]==1;
 cout<<"最優樹爲:"<<endl;
 for(i=0;i<n;i++)
 {
  for(int j=0;j<n;j++)
   cout<<b[i][j]<<' ';
  cout<<endl;
 }
 return 0;
} 
bool bestTree(int m)
{
 if(m==0)
  d=1;
 if(d==1)
  return 0;
 int i,min=-1,fi,fj;
 for(i=0;i<n;i++)
  for(int j=i;j<n;j++)
   if(((a[i][j]>0)&&a[i][j]<min)||(a[i][j]>0)&&min==-1)
   {
    min=a[i][j];
    fi=i;fj=j;
   }
 a[fi][fj]=-1;
 if(c[fi][fj]==1||c[fj][fi]==1)
 {
  bestTree(m);
  return 0;
 }
 b[fi][fj]=1;
 Closure();
 bestTree(m-1);
  
}
void Closure()
{
 int i,t[10],x=0;
 for(i=0;i<n;i++)
  for(int j=i;j<n;j++)
   c[i][j]=b[i][j];
 for(i=0;i<n;i++)
  for(int j=0;j<n;j++)
   if(c[j][i]==1)
    for(int k=0;k<n;k++)
     c[j][k]+=c[i][k];
 for(i=0;i<n;i++)
 {
  int j;
  for(j=i;j<n;j++)
   if(c[i][j]==1)
    t[x++]=j;
  for(j=0;j<x-1;j++)
   c[t[j]][t[j+1]]=1;
 }
}

示例結果

在這裏插入圖片描述

發佈了39 篇原創文章 · 獲贊 59 · 訪問量 7909
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章