prime算法裸题。
思路:
每次找到从已经连通的节点中找到一个权值最小的边走出去,注意要走到没有连通的节点,因此需要vis数组标记已走的节点。
同时在每次走出去后,要更新这个刚走出去的节点到其他节点的最小值。
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
#include<cctype>
#include<cstring>
#include<cmath>
using namespace std;
int mp[1050][1050];
int dist[1050];
int vis[1050];
const int INF=99999999;
int n,m ;
void prime(int cur)
{
int index,sum=0;
for(int i=2;i<=n;i++)
{
dist[i]=mp[cur][i];
}
for(int i=1;i<=n;i++)
{
int minc=INF,p=-1;
for(int j=1;j<=n;j++)
{
if(vis[j]==0&&dist[j]<minc)
{
minc=dist[j];
p=j;
}
}
vis[p]=1; //标记这个节点是否访问过,如果访问过则必定不会有边再走回此点,否则连通
sum+=minc;//这个算法实际上是找出连通所有点的N条权值相对小的边.在最后一个节点一定可以连回初始点
for(int j=1;j<=n;j++)
{
if(~vis[j]&&dist[j]>mp[p][j])
dist[j]=mp[p][j];//在当前节点处,更新p -> i 的最小值,方便下一次选最小
}
}
cout<<sum<<endl;
}
int main()
{
cin>>n>>m ;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
mp[i][j]=INF;
for(int i=1;i<=m;i++)
{
int x,y,tep;
cin>>x>>y>>tep;
mp[x][y]=tep;
mp[y][x]=tep;
}
prime(1);
}