#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <climits>
using namespace std;
typedef struct
{
int head;
int tail;
int cost;
} Edge;
int heap[3000];
int prior[3000];
int heapSize = 0;
int id2Pos[3000];
bool boolVist[3000];
void InsertHeap(int id)
{
heap[heapSize++] = id;
id2Pos[id] = heapSize-1;
int pos = heapSize-1;
while(pos > 0)
{
int parent = pos-1 >> 1;
if (prior[id] > prior[heap[parent]])
break;
int temp = heap[parent];
heap[parent] = id;
heap[pos] = temp;
id2Pos[id] = parent;
id2Pos[temp] = pos;
pos = parent;
}
}
void DeleteHeap(int id)
{
int pos = id2Pos[id];
if (pos < 0)
return;
heap[pos] = heap[--heapSize];
id2Pos[heap[pos]] = pos;
while(pos < (heapSize>>1))
{
int child = 2*pos +1;
if (child+1 < heapSize && prior[heap[child+1]] < prior[heap[child]])
child++;
if (prior[heap[pos]] <= prior[heap[child]])
break;
int temp = heap[pos];
heap[pos] = heap[child];
heap[child] = temp;
id2Pos[temp] = child;
id2Pos[heap[pos]] = pos;
pos = child;
}
}
int PopMin()
{
int id = heap[0];
DeleteHeap(id);
return id;
}
// --------------------------------------
int PrimMST(vector<vector<int>> &V, vector<Edge> &E)
{
int nV = V.size();
int nE = E.size();
// ---- Initialize ------
/*for (int i = 0; i<nV; i++)
{
int m = INT_MAX;
for (int j=0; j<V[i].size(); j++)
{
if (m < E[V[i][j]].cost)
m = E[V[i][j]].cost;
}
prior[i] = m;
InsertHeap(i);
}*/
for (int i=0; i < nV; i++)
{
prior[i] = INT_MAX;
id2Pos[i] = -1;
boolVist[i] = false;
}
int mE = INT_MAX;
int idmE = 0;
for (int i=0; i<nE; i++)
{
if(mE > E[i].cost)
{
mE = E[i].cost;
idmE = i;
}
}
prior[E[idmE].head-1] = mE;
InsertHeap(E[idmE].head-1);
// --------- Prim ----------------
int smst = -mE;
while(heapSize >0)
{
int u = PopMin();
smst += prior[u];
boolVist[u] = true;
for (int i=0; i<V[u].size(); i++)
{
int s = E[V[u][i]-1].head -1;
int v = E[V[u][i]-1].tail -1;
int c = E[V[u][i]-1].cost;
if (!boolVist[s])
{
DeleteHeap(s);
prior[s] = min(prior[s], c);
InsertHeap(s);
}
if (!boolVist[v])
{
DeleteHeap(v);
prior[v] = min(prior[v], c);
InsertHeap(v);
}
}
}
return smst;
}
int main()
{
ifstream infile;
infile.open("edges.txt");
// ------------------------
string line;
std::stringstream ss;
getline(infile, line);
ss << line;
int nV, nE;
ss >> nV;
ss >> nE;
// ------- Initialize ------------
vector<vector<int>> V(nV);
vector<Edge> E(nE);
// -------------------------------
ss.clear();
line.clear();
int n =0;
while(getline(infile, line) && n<nE)
{
ss << line;
int h;
int t;
int c;
ss >> h;
ss >> t;
ss >> c;
E[n].head = h;
E[n].tail = t;
E[n].cost = c;
V[h-1].push_back(n+1);
V[t-1].push_back(n+1);
n++;
ss.clear();
line.clear();
}
// -----------------------------------
int cmst = PrimMST(V, E);
cout << cmst << endl;
/*for (vector<int>::iterator it = mst.begin(); it != mst.end(); it++)
{
cout << *it << endl;
}*/
// -----------------------------------
infile.close();
return 0;
}
参考:
【1】Dijkstra's algorithm http://blog.csdn.net/lsxpu/article/details/41445299
【2】Prim算法与Dijkstra算法的区别 http://blog.csdn.net/superdiablo/article/details/6173001