Kruskal最小生成树算法代码实现(c++)

#include <iostream>
#include <vector>
#include <queue>
#include <fstream>
#include <string>

using namespace std;

//union-find class
class UF{
    private:
	vector<int> id;
	vector<int> sz;
	int count;
    public:
	UF(int N)
	{
	    count = N;
	    for(int i=0;i<N;i++){
		id.push_back(i);
		sz.push_back(1);
	    }
	}
	int countComps(){
	    return count;
	}
	bool connected(int p,int q){
	    return findId(p)==findId(q);
	}

	int findId(int p){
	    while(p != id[p]){
		id[p] = id[id[p]];
		p = id[p];
	    }		
	    return p;
	}
	
	void unionComps(int p,int q){
	    int i = findId(p);	
	    int j = findId(q);	

	    if(i == j) return;

	    if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; }
	    else	       { id[j] = i; sz[i] += sz[j]; }

	    count--;
	}
};

//Weighted Edge and its Graph
struct Edge{
    int v;
    int w;
    double weight;
};

using EdgeLine = vector<Edge>;
class EdgeWeightedGraph{
    public:
	EdgeWeightedGraph(int V){
	    this->V = V; this->E = 0;
	    for(int v=0;v<V;v++){
		EdgeLine el;
		adj.push_back(el);
	    }
	}

	EdgeWeightedGraph(string fileIn)
	{
	    ifstream fin(fileIn);
	    fin>>V>>E;	    
	    for(int v=0;v<V;v++){
		EdgeLine el;
		adj.push_back(el);
	    }
	    const int edges = E;
	    for(int i=0;i<edges;i++){
			Edge tmp;
			fin>>tmp.v>>tmp.w>>tmp.weight;
			adj[tmp.v].push_back(tmp);
			adj[tmp.w].push_back(tmp);
			E++;
	    }
	}
	
	int getV() {return V;}
	int getE() {return E;}

	void addEdge(Edge e){
	    int v = e.v, w = e.w;
	    adj[v].push_back(e);
	    adj[w].push_back(e);
	    E++;
	}

	EdgeLine getEdgeLine(int v){
	    return adj[v];
	} 

    private:
	int V;
	int E;
	vector<EdgeLine> adj;
};

//Edge compare struct
struct CmpEdge{
	bool operator()(Edge& e1,Edge& e2){
		return e1.weight > e2.weight;
	}
};

using MST = queue<Edge>;
class KruskalMST{
    public:
	KruskalMST(EdgeWeightedGraph G)
	{
	    //MinPQ
	    priority_queue<Edge, vector<Edge>, CmpEdge> pq;
	    for(int i=0;i<G.getV();i++){
		EdgeLine el = G.getEdgeLine(i);
		for(auto x : el){
		    if(x.v==i) {pq.push(x);}
		}
	    }
	    //UF
	    UF uf(G.getV());

	    while(!pq.empty() && (mst.size() < G.getV()-1)){
		Edge e = pq.top();
		pq.pop();
		int v=e.v,w=e.w;
		if(uf.connected(v,w))	continue;
		uf.unionComps(v,w);
		mst.push(e);
	    }
	}
	MST edges() {return mst;}
	double weight(){
	    double wt = 0.0;
	    while(!mst.empty()){
		Edge e = mst.front();
		wt += e.weight;
		mst.pop();
	    }
	    return wt;
	}
    private:
	MST mst;
};

int main(int argc,char *argv[])
{
    string filename = argv[1];
    //cout<<"Input filename:"<<endl;
    //cin>>filename;
    EdgeWeightedGraph G(filename);

    KruskalMST klMST(G);
    MST mst = klMST.edges(); 
    /*
    while(!mst.empty()){
    Edge e = mst.front();
    cout<<e.v<<"-"<<e.w<<" "<<e.weight<<endl;
    mst.pop();
    }
    */
    cout<<"Edges in the mst: "<<mst.size()<<endl;
    cout<<"Weight of the mst: "<<klMST.weight()<<endl;
    return 0;
}


程序运行结果测试:

1.

date +%s.%N;./graphpa.exe tinyEWG.txt;date +%s.%N
1450197763.375439900
Edges in the mst: 7
Weight of the mst: 1.81
1450197763.479829700

2.

date +%s.%N;./graphpa.exe mediumEWG.txt;date +%s.%N
1450197826.173859800
Edges in the mst: 249
Weight of the mst: 10.4635
1450197826.300132800

3.

date +%s.%N;./graphpa.exe largeEWG.txt;date +%s.%N
1450197882.677610400
Edges in the mst: 999999
Weight of the mst: 647.663
1450197913.652838600

测试数据在这下载:

http://algs4.cs.princeton.edu/code/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值