思路:从当前的某一点出发,每次选择当前能到达最小值的点,然后标记访问过的点和更新能到达的点,重复执行直至所有点都被访问过。
代码:
#include<iostream>
using namespace std;
const int maxn = 1000+10;
const int INF = 0x3fffffff; // 无穷的一半
int map[maxn][maxn]; //存图
int dis[maxn];
int visited[maxn];
int m,n;
void init(){ //map的初始化
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
map[i][j] = INF;
}
int prim(int m){
int t,min,ans=0;
int i, j;
memset(visited,0,sizeof(visited)); //标记函数的初始化,初始值为0.
for(i=1; i<=m; i++){
dis[i] = map[1][i];
}
visited[1] = 1; //标记使用过
for(i=1; i<m; i++){
min = INF;
t = -1;
for(j=1; j<=m; j++){
if(!visited[j] && dis[j] < min){
min = dis[j];
t = j;
}
}
if(t == -1) //没有最少生成树时直接返回
return INF;
ans += min;
visited[t] = 1;
for(int k=1; k<=m; k++){
if(!visited[k] && dis[k] > map[t][k]){ //没有使用过并且比当前更优时替换
dis[k] = map[t][k];
}
}
}
return ans;
}
int main(){
int a, b, t;
while(cin>>n>>m, n){ // n为边的条数,m 为点的个数
init();
while(n--){
cin>>a>>b>>t;
map[a][b] = map[b][a] = t;
}
t = prim(m);
if(t != INF)
cout<<t<<endl;
else
cout<<"没有最小生成树"<<endl;
}
return 0;
}