最小生成树
Posted abc1604831024
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小生成树相关的知识,希望对你有一定的参考价值。
参考博客:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html
Prim算法
从任意一点开始,找到与之连接的边,然后放入优先队列ee,找到权值最小的边,把这条边所连接的点标记一下,然后把与这个点连接的边放入优先队列ee(如果此边的终点没有被标记),最后直到所有的点全部标记。
Kruskal算法
先把边从大到小排序,然后依次取边,如果边的两个端点已经连接就直接丢掉,否者则加入答案中,直到遍历过所有边。
#include <iostream> #include <algorithm> #include <cstring> #include <queue> #include <vector> #include <cstdio> using namespace std; struct sdsd { int from,n,to,ne; friend bool operator <(sdsd a,sdsd b) { return a.n>b.n; } }; bool mpb (sdsd a,sdsd b) { return a.n<b.n; } sdsd aa[155]; int bb[155],cc[155]; void Prim() { priority_queue <sdsd ,vector <sdsd>,less <sdsd> > ee; vector <int > dd; for (int i=bb[1];i!=-1;i=aa[i].from) ee.push (aa[i]); dd.push_back(1); while (!ee.empty()) { sdsd t=ee.top(); ee.pop(); //cout <<t.to<<endl; if (!cc[t.to]) { cout <<t.ne<<" "<<t.to<<endl; cc[t.to]=1; } for (int i=bb[t.to];i!=-1;i=aa[i].from) { if (!cc[aa[i].to]) { ee.push(aa[i]); } } } } void Kruskal(int m) { memset (cc,-1,sizeof (cc)); sort (aa,aa+2*m,mpb); for (int i=0;i<2*m;i=i+2) { int a=aa[i].ne; int b=aa[i].to; while (cc[a]!=-1) a=cc[a]; while (cc[b]!=-1) b=cc[b]; if (a==b) continue; cc[a]=b; cout <<aa[i].ne<<" "<<aa[i].to<<endl; } } int main () { freopen ("data.in","r",stdin); int n=9,m=12; memset (aa,-1,sizeof (aa)); memset (bb,-1,sizeof (bb)); for (int i=0;i<m;i++) { int a,b,c; cin >>a>>b>>c; aa[2*i].to=a; aa[2*i].from=bb[b]; bb[b]=2*i; aa[2*i].n=c; aa[2*i].ne=b; aa[2*i+1].ne=a; aa[2*i+1].to=b; aa[2*i+1].from=bb[a]; bb[a]=2*i+1; aa[2*i+1].n=c; } Prim(); cout <<endl; Kruskal(m); }
运行结果:
以上是关于最小生成树的主要内容,如果未能解决你的问题,请参考以下文章