想看更多的解题报告: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; }