Prim
Prim最小生成树算法,以任意节点为根,找出与之相邻的所有便,再将新节点更新并以此节点为根继续进行,dis为已用点到未用点的最短距离。适用于稠密图,时间复杂度O(N^2)。
inline int prim(){
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
int cnt=dis[1]=0,x=1,ans=0;/*初始以1为根*/
for(int i=h[1];i;i=e[i].next){
int y=e[i].to;
dis[y]=min(dis[y],e[i].w);
}
while(++cnt<n){
int mi=0x7fffffff;
vis[x]=1;
for(int i=1;i<=n;i++)if(!vis[i]&&dis[i]<mi)mi=dis[i],x=i;
ans+=mi;
for(int i=h[x];i;i=e[i].next){
int y=e[i].to;
dis[y]=min(dis[y],e[i].w);
}
}
if(ans>=0x3f3f3f3f)return false;/*存在点没有被更新过,图不连通,也可以判断存在未访问的节点*/
return ans;
}
堆优化prim,时间复杂度O((N+M)*log2(N))。
inline int prim(){
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
int cnt=dis[1]=0,ans=0;
q.push({0,1});
while(!q.empty()&&cnt<n){
int x=q.top().second,w=q.top().first;
q.pop();
if(vis[x])continue;
cnt++;/*新选入一条边*/
ans+=w;
vis[x]=1;
for(int i=h[x];i;i=e[i].next){
int y=e[i].to;
if(dis[y]>e[i].w){/*松弛操作*/
dis[y]=e[i].w;
q.push({dis[y],y});/*入队*/
}
}
}
if(cnt<n)return false;/*图不连通*/
return ans;
}

浙公网安备 33010602011771号