#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
class UF
{
public:
int *id;
int *sz;
UF(int N)
{
id=new int[N];
sz=new int[N];
for(int i=0;i<N;i++)
id[i]=i;
memset(sz,1,N);
}
bool connected(int v,int w)
{
return find(v)==find(w);
}
int find(int v)
{
while(v!=id[v])
v=id[v];
return v;
}
void unio(int v,int w)
{
int i=find(v);
int j=find(w);
if(i==j)
return ;
if(sz[i]>sz[j])
{
id[j]=i;
sz[i]+=sz[j];
}
else
{
id[i]=j;
sz[j]+=sz[i];
}
}
};
class Edge
{
public:
int v,w,weight;
Edge(int _v,int _w,int _weight)
{
v=_v;
w=_w;
weight=_weight;
}
int either()
{
return v;
}
int other(int virtex)
{
if(virtex==w)
return v;
else
return w;
}
bool operator < (const Edge& e) const
{
return weight>e.weight;
}
};
const int N=55;
vector<Edge> vec[N];
priority_queue<Edge> pq;
int v,ans;
void MST()
{
int ver=0;
for(int i=0;i<v;i++)
{
for(Edge e:vec[i])
{
int w=e.other(i);
if(w>i)
pq.push(e);
}
}
UF uf(v);
while(!pq.empty() && ver<v-1)
{
Edge e=pq.top();
pq.pop();
int p=e.either();
int q=e.other(p);
if(uf.connected(p,q))
continue;
uf.unio(p,q);
ans+=e.weight;
}
}
int main()
{
cin>>v;
for(int i=0;i<v;i++)
{
for(int j=0;j<v;j++)
{
int a;
cin>>a;
if(a!=0)
{
Edge e(i,j,a);
vec[i].push_back(e);
vec[j].push_back(e);
}
}
}
MST();
cout<<ans<<endl;
return 0;
}
算法第四版---最小生成树Kruskal算法
最新推荐文章于 2024-11-06 11:05:01 发布
本文介绍了一个使用C++实现的并查集(Union-Find)和Prim算法来求解带权无向图的最小生成树问题。通过UF类实现连接和查找操作,利用优先队列维护边的权重,MST函数计算并合并最小权重的边,直至生成树构建完成。
摘要由CSDN通过智能技术生成