// Prim算法實現(采用鄰接表存儲).cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdafx.h"
#include<iostream>
#define MAX 100
#define Infinity 65535
typedef int WeiType;
using namespace std;
struct edgeNode
{
int no; //邊端的序號
char info; //邊端的名稱
WeiType weight; //邊的權值
struct edgeNode * next; //下一個
};
struct vexNode
{
char info; //節點名稱
struct edgeNode *link; //與之相連的端點
};
//存儲節點信息
vexNode adjlist[MAX];
//訪問標志
bool visited[MAX];
//lowcost[j]存儲從開始節點到節點j的最小花費
WeiType lowcost[MAX];
//parent[j]表示節點j的前驅節點
int parent[MAX];
//建立鄰接表存儲
void createGraph(vexNode *adjlist,const int n,const int e,const int v0)
{
int i;
for(i=1;i<=n;i++)
{
cout<<"請輸入節點"<<i<<"的名稱:";
cin>>adjlist[i].info;
adjlist[i].link = NULL;
//初始化
visited[i] = false;
lowcost[i] = Infinity;
parent[i] = v0;
}
edgeNode *p1,*p2;
int v1,v2;
WeiType weight;
for(i=1;i<=e;i++)
{
cout<<"請輸入邊"<<i<<"的二端的節點序號:";
cin>>v1>>v2;
cout<<"此邊的權值:";
cin>>weight;
p1 = (edgeNode*)malloc(sizeof(edgeNode));
p2 = (edgeNode*)malloc(sizeof(edgeNode));
p1->no = v1;
p1->weight = weight;
p1->info = adjlist[v1].info;
p1->next = adjlist[v2].link;
adjlist[v2].link = p1;
p2->no = v2;
p2->weight = weight;
p2->info = adjlist[v2].info;
p2->next = adjlist[v1].link;
adjlist[v1].link = p2;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int cases;
cout<<"請輸入案例的個數:";
cin>>cases;
while(cases--)
{
int n,e;
cout<<"請輸入節點數:";
cin>>n;
cout<<"請輸入邊數:";
cin>>e;
cout<<"請輸入從哪一個節點開始:";
int v;
cin>>v;
int i,j;
//最小生成樹的權值總和
WeiType sum = 0;
createGraph(adjlist,n,e,v);
edgeNode *p,*q;
p = adjlist[v].link;
visited[v] = true;
while(p!=NULL)
{
lowcost[p->no] = p->weight;
p = p->next;
}
WeiType minCost;
for(i=1;i<n;i++)
{
minCost = Infinity;
int k;
for(j=1;j<=n;j++)
{
if(minCost>lowcost[j]&&!visited[j])
{
minCost = lowcost[j];
k = j;
}
}
sum += minCost;
visited[k] = true;
q = adjlist[k].link;
while(q != NULL)
{
if(!visited[q->no]&&q->weight<lowcost[q->no])
{
lowcost[q->no] = q->weight;
parent[q->no] = k;
}
q = q->next;
}
}
cout<<"最小生成樹的邊集為:"<<endl;
for(i=1;i<=n;i++)
if(i!=v)
cout<<"("<<adjlist[parent[i]].info<<","<<adjlist[i].info<<")"<<" ";
cout<<endl;
cout<<"最小生成樹的權值為:"<<sum<<endl;
}
system("pause");
return 0;
}
-----------------------------------------------------程序測試--------------------------------------------------
請輸入案例的個數:1
請輸入節點數:9
請輸入邊數:14
請輸入從哪一個節點開始:2
請輸入節點1的名稱:a
請輸入節點2的名稱:b
請輸入節點3的名稱:c
請輸入節點4的名稱:d
請輸入節點5的名稱:e
請輸入節點6的名稱:f
請輸入節點7的名稱:g
請輸入節點8的名稱:h
請輸入節點9的名稱:i
請輸入邊1的二端的節點序號:1 2
此邊的權值:4
請輸入邊2的二端的節點序號:1 8
此邊的權值:8
請輸入邊3的二端的節點序號:2 3
此邊的權值:8
請輸入邊4的二端的節點序號:2 8
此邊的權值:11
請輸入邊5的二端的節點序號:3 4
此邊的權值:7
請輸入邊6的二端的節點序號:3 6
此邊的權值:4
請輸入邊7的二端的節點序號:3 9
此邊的權值:2
請輸入邊8的二端的節點序號:4 5
此邊的權值:9
請輸入邊9的二端的節點序號:4 6
此邊的權值:14
請輸入邊10的二端的節點序號:5 6
此邊的權值:10
請輸入邊11的二端的節點序號:6 7
此邊的權值:2
請輸入邊12的二端的節點序號:7 8
此邊的權值:1
請輸入邊13的二端的節點序號:7 9
此邊的權值:6
請輸入邊14的二端的節點序號:8 9
此邊的權值:7
最小生成樹的邊集為:
(b,a) (b,c) (c,d) (d,e) (c,f) (f,g) (g,h) (c,i)
最小生成樹的權值為:37
請按任意鍵繼續. . .
作者 heyongluoyao8