想看更多的解题报告:http://blog.csdn.net/wangjian8006/article/details/7870410
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:谷仓之间有一些路径长度,然后要在这些谷仓之间建立一些互联网,花费的成本与长度成正比,,并且要使这些边连起来看的像一课“树”,然后使成本最大
解题思路:最大生成树
用kruskal在最小生成树的基础上,将排序从大到小排序,这样就是一个最大生成树了
/*
Memory 472K
Time 63MS
*/
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXV 1001
#define MAXM 20010
class CEdge{
public:
int m_start,m_end,m_value;
};
class CMaxSpanTree{
private:
CEdge *m_edge; //结构体保存边的信息
int *m_nParentSet; //保存并查集的父亲数组
int m_nVerCount; //点的个数
int m_nEdgeCount; //边的个数
bool m_bFlag; //判断是否是连通图
int m_nAns; //最大生成树的边和
bool Union(int x,int y); //并查集的合并函数
int find(int x); //并查集寻找根节点函数
public:
CMaxSpanTree(int VerCount);
~CMaxSpanTree();
void AddEdge(int s,int t,int w); //增加一条边
void Run(); //运行,kruskal算法计算最大生成树
int GetAns(); //得到答案
};
bool cmp(CEdge a,CEdge b){ //这边用kruskal算法时使排序按照边值从大到小排序
return a.m_value>b.m_value;
}
CMaxSpanTree::CMaxSpanTree(int nVerCount){
m_edge = new CEdge[MAXM];
m_nParentSet = new int[MAXV];
m_nEdgeCount = 0;
m_nVerCount = nVerCount;
m_nAns = 0;
m_bFlag = false; //初始设为不连通
for(int i = 0;i <= nVerCount;i++){ //并查集父亲数组初值
m_nParentSet[i] = i;
}
}
CMaxSpanTree::~CMaxSpanTree(){
delete []m_edge;
delete []m_nParentSet;
}
void CMaxSpanTree::AddEdge(int s,int t,int w){
m_edge[m_nEdgeCount].m_start = s;
m_edge[m_nEdgeCount].m_end = t;
m_edge[m_nEdgeCount].m_value = w;
m_nEdgeCount++;
}
int CMaxSpanTree::find(int x){
if(x == m_nParentSet[x])
return x;
int rt = find(m_nParentSet[x]);
m_nParentSet[x] = rt;
return rt;
}
bool CMaxSpanTree::Union(int x,int y){
int fx = find(x);
int fy = find(y);
if (fx == fy){
return 0;
}
m_nParentSet[fx] = fy;
return 1;
}
void CMaxSpanTree::Run(){
sort(m_edge,m_edge+m_nEdgeCount,cmp);
int nCnt = 0 ,i;
for(i = 0;i < m_nEdgeCount;i++){
if(Union(m_edge[i].m_start,m_edge[i].m_end)){
m_nAns += m_edge[i].m_value;
nCnt++;
if(nCnt == m_nVerCount - 1){
m_bFlag = true;
return;
}
}
}
}
int CMaxSpanTree::GetAns(){
return m_bFlag?m_nAns:-1;
}
int main(){
int n,m;
int a,b,c;
while(~scanf("%d%d",&n,&m)){
CMaxSpanTree tree(n);
while(m--){
scanf("%d%d%d",&a,&b,&c);
tree.AddEdge(a,b,c);
}
tree.Run();
cout<<tree.GetAns()<<endl;
}
return 0;
}