POJ 2377题
//题目大意:最大生成树
//解题思路:在排序的时候按从大到小排即可,其余与Kruskal算法一样
//注意:如果使用Prime算法注意考虑重边的情况,Kruskal算法不必考虑重边的情况(因为是将边进行排序,当一条边已经加入的时候,不可能加入重边)
#include <stdio.h>
#include <algorithm>
using namespace std;
#define edgesize 20001
#define nodesize 1001
typedef struct node
{
int start;
int end;
__int64 w;
}node;
node edges[edgesize];
node record[edgesize];
int final[nodesize];
int nodes[nodesize];
bool cmp(node a,node b) //此处与最小生成树不同,排序时从大到小排
{
return (a.w>b.w);
}
int findroot(int n)
{
if(final[n] == n)
return n;
else
final[n] = findroot(final[n]);
return final[n];
}
int main()
{
//freopen("1.txt","r",stdin);
int N,M;
while(scanf("%d%d",&N,&M)!=EOF)
{
int a,b,c;
for(int i=1;i<M+1;++i)
{
scanf("%d%d%d",&a,&b,&c);
edges[i].start = a;
edges[i].end = b;
edges[i].w = c;
}
sort(edges+1,edges+M+1,cmp);
for(int i1=1;i1<N+1;++i1)
{
final[i1] = i1;
nodes[i1] = 1;
}
int flag = 0;
__int64 sum = 0;
for(int i2=1;i2<M+1;++i2)
{
int start = edges[i2].start;
int end = edges[i2].end;
__int64 w = edges[i2].w;
int startroot = findroot(start);
int endroot = findroot(end);
if(startroot!=endroot)
{
flag ++;
record[flag].start = start;
record[flag].end = end;
record[flag].w = w;
sum += w;
if(nodes[startroot]>=nodes[endroot])
{
final[endroot] = startroot;
nodes[startroot] += nodes[endroot];
}
else
{
final[startroot] = endroot;
nodes[endroot] += nodes[startroot];
}
}
}
//最后别忘了判断一下是否存在生成树
if(flag == N-1)
printf("%I64d\n",sum);
else
printf("-1");
}
return 0;
}