zoukankan      html  css  js  c++  java
  • Prim算法

    用c++实现了Prim算法。用了c++的优先队列。

    代码仅供参考:

    #include <iostream>
    #include <string>
    #include <stack>
    #include <fstream>
    #include <sstream>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    /**********边表************/
    class EdgeNode
    {
    public:
    	int adjvex;
    	int cost;
    	int head;
    	EdgeNode *next;
    	EdgeNode(int _head, int _adj, int _cost,EdgeNode *n = NULL) : head(_head), adjvex(_adj), cost(_cost), next(n) {}
    };
    /*=========顶点表============*/
    class VertexNode
    {
    public:
    	int data;
    	EdgeNode *firstEdge;
    	VertexNode()
    	{
    		firstEdge = NULL;
    	}
    };
    /*********自定义比较函数(优先队列使用)************/
    class mycompare
    {
    	bool reverse;
    public:
    	mycompare(const bool &re = true)
    	{
    		reverse = re;	
    	}
    	bool operator() (EdgeNode *a, EdgeNode *b) const
    	{
    		//从小到大排列, 优先队列,!mycompare,按照cost的从小到大排列
    		if(reverse) return (a->cost > b->cost); 
    		else {
    			return (a->cost < b->cost);
    			//从小到大排列, 优先队列,!mycompare,按照cost的从大到小排列
    		}
    
    	}
    
    };
    /*********无向图的数据结构*************/
    class Graph 
    {
    public:
    /*********初始化图的邻接表数据***************/
    	Graph()
    	{
    		ifstream fin("pp.txt");
    		string line;
    		stringstream stream;
    		if(getline(fin, line))
    		{
    			stream.clear();
    			stream << line;
    			stream >> numVertexes;
    			stream >> numEdges;
    		}
    		init_adjList();
    		while(getline(fin, line))
    		{
    			int vertex, adjacent,  _cost;
    			stream.clear();
    			stream << line;
    			stream >> vertex;
    			stream >> adjacent;
    			stream >> _cost;
    			addEdge(vertex, adjacent, _cost);			
    		}
    	}
    /********初始化邻接表的顶点表*******/
    	void init_adjList()
    	{
    		adjList.resize(numVertexes);
    		for(int i = 0; i < numVertexes; i++)
    		{	
    			adjList[i].data = i;
    		}		
    	}
    
    
    /************加边,头插法*****************/
    	void addEdge(int a, int b, int _cost)
    	{
    		EdgeNode *enode1 = new EdgeNode(a-1, b-1, _cost, NULL);
    		EdgeNode *enode2 = new EdgeNode(b-1, a-1, _cost, NULL);
    		adjList[a-1].data = a-1;
    		enode1->next = adjList[a-1].firstEdge;
    		adjList[a-1].firstEdge = enode1;
    		adjList[b-1].data = b-1;
    		enode2->next = adjList[b-1].firstEdge;
    		adjList[b-1].firstEdge = enode2;
    	}
    /************打印看结果************/
    	void print()
    	{
    		ofstream fout;
    		fout.open("primoutput.txt");
    		for(int i = 0; i < numVertexes; i++)
    		{
    			fout << "vertex:" << adjList[i].data << " adj:" ;
    			EdgeNode *tmp = new EdgeNode(0, 0, 0 );
    			tmp = adjList[i].firstEdge;
    			while(tmp)
    			{
    				fout << tmp->adjvex << "cost: " << tmp->cost << " ";
    				tmp = tmp->next;
    			}
    			fout << endl;
    		}
    	}
    /*********************************/
    public:
    	int numVertexes; //顶点数目
    	int numEdges;	 //边数目
    	vector<VertexNode> adjList;   //图的邻接表
    };
    /***********prim算法实现**********/
    class Prims
    {
    public:
    	Prims(Graph graph)
    	{
    		int s = 0;
    		length = graph.numVertexes; //顶点数目
    		tree.resize(length); 
    		marked.push_back(s); //将初始顶点加入最小生成树中
    		pq.push(graph.adjList[s].firstEdge); //将初始顶点的第一条边加入队列
    		while(!pq.empty())
    		{
    			EdgeNode *p = new EdgeNode(0,0,0);
    			p = graph.adjList[s].firstEdge;
    			while(p)
    			{
    				if(!is_marked(p->adjvex))
    				{
    					pq.push(p);
    				}
    				p = p->next;
    			}
    
    			EdgeNode *p1 = new EdgeNode(0,0,0);
    			p1 = pq.top();
    			pq.pop();
    			s = p1->adjvex;
    			if(!is_marked(s)) //如果没有加入进最小生成树
    			{
    				marked.push_back(p1->adjvex);
    				tree[p1->head].push_back(p1->adjvex); //将边加入最小生成数
    				sum += p1->cost;  //cost的累加
    			}
    		
    		}
    
    	}
    /*******************判断是否加入最小生成树***************/	
    	bool is_marked(int a)
    	{
    	
    		for(int i = 0; i < marked.size(); i++)
    		{
    			if(marked[i] == a)
    			{
    				return true;
    			}
    		}
    		return false;
    	}
    /***************输出看结果**************/
    	void write()
    	{
    		ofstream fout;
    		fout.open("tree.txt");
    		for(int i = 0; i < length; i++)
    		{
    			fout << "tree[" << i << "]: " ;
    			for(int j = 0; j < tree[i].size(); j++)
    			{
    				fout << tree[i][j] << " ";
    			}
    			fout << endl;
    		}
    	}
    
    
    public:
    	int length;
    	int sum = 0;
    	vector<int> marked;//最小生成树木的顶点表
    	vector<vector<int> > tree; //最小生成树的边 ,数组存储
    	priority_queue<EdgeNode*, vector<EdgeNode*>, mycompare> pq; //优先队列
    };
    
    
    int main()
    {
    	Graph graph;
    	graph.print();
    	Prims _prims(graph);
    	_prims.write();
    	cout << "sum: " << _prims.sum << endl;
    	return 0;
    }
    

      

    The Safest Way to Get what you Want is to Try and Deserve What you Want.
  • 相关阅读:
    变量的创建和初始化
    HDU 1114 Piggy-Bank (dp)
    HDU 1421 搬寝室 (dp)
    HDU 2059 龟兔赛跑 (dp)
    HDU 2571 命运 (dp)
    HDU 1574 RP问题 (dp)
    HDU 2577 How to Type (字符串处理)
    HDU 1422 重温世界杯 (dp)
    HDU 2191 珍惜现在,感恩生活 (dp)
    HH实习 acm算法部 1689
  • 原文地址:https://www.cnblogs.com/Shinered/p/9129874.html
Copyright © 2011-2022 走看看