最小生成樹
構造連通圖的最小代價生成樹
普里姆算法Prim
Prim算法用到的是鄰接矩陣,具體方法就是構造一個一維數組初始化值位一個特別大的數(再鄰接矩陣裏面就已經存好值了),然後從起始點開始找與之相連的點,並存到一維數組裏面;進行第一輪循環,找出相連點裏面權值最小的,標記這個最小值和點的下標,然後遍歷一維數組,找出與這個最小權值點相連的點,再把對於權值存到一維數組裏面,再重複上面的步驟,直到完全構成一個聯通圖。
代碼
//G是鄰接矩陣,n爲點數目
void Prim(int G[][],int n)
{
int min,i,j;
int a[1010];//存相關頂點下標
int low [1010];//一維數組存權值
low[0]=0;
for(int i=1;i<n;i++)
{
low[i]=G[0][i];
a[i]=0;
}
for(int i=1;i<n;i++)
{
min=-9999;
j=1;
k=0;
while(j<n)
{
if(low[j]!=0&&low[j]<min)
{
min=j;k=j;
}
j++;
}
low[k]=0;
for(j=1;j<n;j++)
{
if(!low[i]&&G[k][j]<min)
{
low[j]=G[k][j];
a[j]=k;
}
}
}
}
克魯斯卡爾算法Kruskal
Kruskal算法需要把鄰接矩陣先轉換爲一個邊集數組,就是按權值遞增順序存的一個結構體數組。在剩下的所有未選取的邊中,找最小邊,如果和已選取的邊構成迴路,則放棄,選取次小邊。
struct {
int s;
int e;
int weigh;
}Edge;
void Kruskal(int G[][],int n)
{
int i,n,m;
int parent[1001];
Edge edges[1010];
memset(parent,0,sizeof(a));
for(int i=0;i<n;i++)
{
n=Find(parent,edges[i].s);
m=Find(parent,edgs[i].e);
if(n!=m)
{
parent[n]=m;
printf("%d %d %d",edgs[i].s,edgs[i].e,edgs[i].weight);
}
}
}
int Find(int *parent,int f)
{
while(parent[f]>0)
f=parent[f];
return f;
}