您的位置:首页 > 其它

kruscal最小生成树算法

2009-09-14 10:13 381 查看
下面是kruscal最小生成树算法,用了并查集和优先队列:

// kruscal.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <queue>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
class  UFset
{
public:
vector<int> parent;
UFset(int n);
int  Find( int );
void  Union( int ,  int );
} ;

UFset::UFset(int n)
{
parent.resize(n, -1);//根节点放置的是当前树上的节点数量的负值,初始化是为-1,表示只有一个元素
}

int  UFset::Find( int  x)
{
if  (parent[x]  <=   0 )
return  x;
else
{
parent[x]  =  Find(parent[x]);
return  parent[x];
} //  压缩路径
}

void  UFset::Union( int  x,  int  y)
{
int  pX  =  Find(x);   // 根节点的位置
int  pY  =  Find(y);
int  tmp;

tmp  =  parent[pX]  +  parent[pY];  //  加权合并

if  (pX  !=  pY)//不在一个集合中
{
if  (parent[pX]  >  parent[pY])
{
parent[pX]  =  pY;
parent[pY]  =  tmp;
}
else
{
parent[pY]  =  pX;
parent[pX]  =  tmp;
}
}

}

struct Edge
{
int dis;
int v,w;
bool operator<(const Edge &e1)const
{
return dis<e1.dis;
}
bool operator>(const Edge &e1)const
{
return dis>e1.dis;
}
Edge(int vv,int ww,int diss)
{
v=vv;
w=ww;
dis=diss;
}
};

int _tmain(int argc, _TCHAR* argv[])
{

priority_queue<Edge,vector<Edge>,greater<Edge>> e;//边集
priority_queue<Edge,vector<Edge>,less<Edge>> te;//生成树的边集
int p, t;//顶点数,边数

FILE *fp;
fp=fopen("data.txt", "r");
fscanf(fp,"%d %d", &p, &t);

int i;
for(i =0; i < t; i++)
{
int t1, t2, t3;

fscanf(fp, "%d %d %d", &t1, &t2, &t3);
Edge x(t1, t2, t3);
e.push(x);
}

UFset u(p+1);

while(e.size())
{
Edge x=e.top();
e.pop();
int a=u.Find(x.w);
int b=u.Find(x.v);
if (a!=b)
{
te.push(x);
cout<<x.v <<"-"<<x.w<<":"<<x.dis<<endl;
u.Union(a,b);
}
}

return 0;
}


数据文件data.txt格式如下:

6 10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6


其中6表示顶点数目,10表示边树(注:为无向图)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: