图的最小生成树
Prim算法
核心思想:贪心的将一个又一个点加入集合,而加入的每个点都尽可能使边权最小,这样可以使用STL的priority_queue来维护。
struct edge{int to,cost;};//to表示边的终点,cost表示权值
typedef pair<int,int> P;//P.first表示已有点集到P.second这个点的边权最小值
priority_queue <P,vector<P>,greater<P> >que;//用于存储最小边权值的优先队列
bool visited[MAX_V];//查找点是否被访问
vector<edge> G[MAX_V];
int V;//顶点数
int Prim()
{
for(int i=0;i<V;i++)
{
visited[i]=false;
}
int res=0;
que.push(0,0);
for(int i=1;i<=V;i++)
{
while(true)
{
P p=que.top();
if(!visited[p.second])
{
res=res+p.first;
for(int j=0;j<G[p.second].size();j++)
{
que.push(P(G[p.second].cost,P(G[p.second].to)));
}
break;
}
}
}
return res;
}
Kruskal算法
核心思想:把边的权值从小到大排一遍,一条一条加入图中,不产生圈即为有效。为了简化,可以用并查集判断是否构成圈。
struct edge{ int u,v,cost};//u为边的起点,v为边的终点,cost为边的权值
bool cmp(const edge& e1,const edge & e2)
{
return e1.cost < e2.cost;
}
edge es[MAX_E];//保存所有的边
int V,E;//顶点数和边数
//init,unite,same函数均为并查集的函数,请跳转至并查集部分
int Kruskal()
{
sort(es,es+E,cmp);
init(V);
int res=0;
for(int i=0;i<E;i++)
{
edge e=es[i];
if(!same(e.u,e.v))
{
unite(e.u,e.v);
res=res+e.cost;
}
}
return res;
}

浙公网安备 33010602011771号