水题一道,关键是理解题目为最小生成树。纯粹为了复习并查集和Kruscal最小生成树。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Edge
{
public:
int nId1,nId2;
int length;
};
class LinkNode
{
public:
LinkNode()
{
nodeID=-1;
length=-1;
nextNode=NULL;
}
int nodeID;
int length;
LinkNode* nextNode;
};
class Node
{
public:
Node()
{
nodeID=0;
parent=NULL;
rank=0;
linkNodes=NULL;
}
int nodeID;
Node* parent;
int rank;
LinkNode* linkNodes;
bool AddLinkNode(Edge edge);
};
bool Node::AddLinkNode(Edge edge)
{
int linkID=-1;
if(edge.nId1==nodeID)
{
linkID=edge.nId2;
}
else
{
linkID=edge.nId1;
}
if(linkNodes==NULL)
{
linkNodes=new LinkNode();
linkNodes->length=edge.length;
linkNodes->nodeID=linkID;
return true;
}
else
{
LinkNode* tLinkNode=linkNodes;
while(tLinkNode->nextNode!=NULL && tLinkNode->nodeID!=linkID)
{
tLinkNode=tLinkNode->nextNode;
}
if(tLinkNode->nextNode==NULL)
{
LinkNode* newLinkNode=new LinkNode();
newLinkNode->length=edge.length;
newLinkNode->nodeID=linkID;
tLinkNode->nextNode=newLinkNode;
return true;
}
else
{
if(tLinkNode->length>edge.length)
{
tLinkNode->length=edge.length;
return true;
}
}
}
return false;
}
class Graph
{
public:
vector<Node> nodeVec;
vector<Edge> edgeVec;
int iNodeNum;
int iEdgeNum;
bool InsertEdge(Edge edge);
};
bool Graph::InsertEdge(Edge edge)
{
if(nodeVec[edge.nId1].AddLinkNode(edge) && nodeVec[edge.nId2].AddLinkNode(edge))
{
edgeVec.push_back(edge);
return true;
}
return false;
}
bool SortEdge(Edge e1,Edge e2)
{
return e1.length<e2.length;
}
void MakeSet(Node& x)
{
x.parent=&x;
x.rank=0;
}
Node* FindSet(Node* node)
{
if(node->parent != node)
{
node->parent=FindSet(node->parent);
}
return node->parent;
}
void LinkTwoTree(Node* pNode1,Node* pNode2)
{
if(pNode1->rank>pNode2->rank)
{
pNode2->parent=pNode1;
}
else if(pNode1->rank<pNode2->rank)
{
pNode1->parent=pNode2;
}
else
{
pNode1->parent=pNode2;
pNode2->rank++;
}
}
void UnionSets(Node* pNode1,Node* pNode2)
{
LinkTwoTree(FindSet(pNode1),FindSet(pNode2));
}
vector<Edge>* MinSpanTree_Kruscal(Graph graph)
{
vector<Edge> *mSpanTree=new vector<Edge>();
for(vector<Node>::iterator nodeIter=graph.nodeVec.begin();nodeIter!=graph.nodeVec.end();nodeIter++)
{
MakeSet(*nodeIter);
}
sort(graph.edgeVec.begin(),graph.edgeVec.end(),SortEdge);
int iUnionNumber=0;
for(vector<Edge>::iterator edgeIter=graph.edgeVec.begin();edgeIter!=graph.edgeVec.end();edgeIter++ )
{
if(FindSet( &graph.nodeVec[edgeIter->nId1-1] ) != FindSet(&graph.nodeVec[edgeIter->nId2-1]))
{
UnionSets(&graph.nodeVec[edgeIter->nId1-1],&graph.nodeVec[edgeIter->nId2-1]);
mSpanTree->push_back(*edgeIter);
}
}
return mSpanTree;
}
int main()
{
Graph graph;
int ai,bi,len;
int n,m;
cin>>n>>m;
graph.iNodeNum=n;
graph.iEdgeNum=m;
for(int i=0;i<n;i++)
{
graph.nodeVec.push_back(Node());
}
for(int i=0;i<m;i++)
{
cin>>ai>>bi>>len;
Edge edge;
edge.nId1=ai;
edge.nId2=bi;
edge.length=len;
graph.edgeVec.push_back(edge);
}
vector<Edge>mSpanTree=*MinSpanTree_Kruscal(graph);
cout<<mSpanTree[mSpanTree.size()-1].length<<endl;
return 0;
}