hrbust 1133报告、MST最小生成树 Kruskal算法

最基本的MST最小生成树的题目、

两种算法

1.prim算法

大致思想是任意选取一个节点a假如集合U  其它节点在集合V

算出a到V中每个节点的最短路径值   将最近的节点从V中删除 加到U中

直到所有节点都加到U中  既是最小生成树

原理是因为每两个节点间最短边必定在最小生成树中、

2.kruskal算法、

利用并查集、

原理是将所有边按权从小到大排序  每一个节点自己在一个集合

按顺序遍历所有边  如果边的两个端点不在一个内

就讲此边加入到最小生成树中

并将他们所在的两个集合合并

直到遍历结束、

过程中将加入生成树边中的权加和记录

既是路径总长度、

代码如下:

#include <iostream>
#include <queue>
using namespace std;
int s[100];
struct root
{
    int a;
    int b;
    int value;
    bool operator<(const root &a) const //查资料来的  不是太明白、 在queue排序中 把value的大小作为关键值
    {
        return a.value<value;
    }
};
priority_queue<root> q;  //优先队列  不是按入队的先后排序 而是按大小排序
int find(int x)
{
    int i=x,tmp;
    while(s[i]!=i)
      i=s[i];
    while(s[x]!=x) //压缩路径  节省时间 将树中所有的节点都直接指向根节点
    {
        tmp=s[x];
        s[x]=i;
        x=tmp;
    }
    return i;
}
void hebin(int a,int b)
{
    int m=find(a);
    int n=find(b);
    if(m!=n)
      s[m]=n;
}
void kruskal()
{
    int js=0;
    root tmp;
    while(!q.empty())
    {
        tmp=q.top();
        q.pop();
        if(find(tmp.a)!=find(tmp.b))
        {
            js+=tmp.value;//记录路径长度
            hebin(tmp.a,tmp.b);
        }
    }
    cout<<js<<endl;
}
int main()
{
    int n;
    root t;
    while(cin>>n)
    {
        if(n==0) break;
        for(int i=1;i<=n;i++)
          s[i]=i;
        for(int i=0;i<(n-1)*n/2;i++)
        {
            cin>>t.a>>t.b>>t.value;
            q.push(t);
        }
        kruskal();
    }
}


你可能感兴趣的:(算法,struct)