很簡單的一題最小生成樹的題目
農民約翰被選爲他們鎮的鎮長!他其中一個競選承諾就是在鎮上建立起互聯網,並連接到所有的農場。當然,他需要你的幫助。 約翰已經給他的農場安排了一條高速的網絡線路,他想把這條線路共享給其他農場。爲了使花費最少,他想鋪設最短的光纖去連接所有的農場。
你將得到一份各農場之間連接費用的列表,你必須找出能連接所有農場並所用光纖最短的方案。
prim 算法
就是從一個點開始衍生,找與此點相連的最短的邊,採用那條邊,獲得另一個點。之後再以這兩個點爲基礎,找與這兩點相連的最短的邊……直到所有點都連在一起。這個方法需要每次把邊排序,很耗時,用堆排能大量縮短時間。學了c++後,可以使用優先隊列,非常方便。
#include<iostream>
#include<queue>
using namespace std;
class list{
public:
int value;//記錄邊值
int x;//記錄於之相連的點
bool friend operator < ( const list &a,const list &b){
return (a.value>b.value);}//由於要的是最小邊,所把優先隊列修改下,把小的放前面
};
const int MAXN=112;
priority_queue<list> Q;
list temp;
int n,sum;
int a[MAXN][MAXN],p[MAXN];//p數組用於記錄點是否以及加入
void push(int x)
{
p[x]=1;
for (int i=1;i<=n;i++)
if (p[i]==0)
{
temp.value=a[x][i];
temp.x=i;
Q.push(temp);
}
}
void prim()
{
int num;記錄已經加入了幾個點了
push(1);//隨便加入一個點0.0
num=1;
while (num!=n)
{
do{
temp=Q.top();
Q.pop();
}while(p[temp.x]==1);//找到一個還沒進入的點
sum+=temp.value;
push(temp.x);//將此點加入
num++;
}
}
int main()
{
int i,j;
cin>>n;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
cin>>a[i][j];
prim();
cout<<sum<<endl;
}
如有不足之處,希望大家指出。