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;
}

posted @ 2010-04-30 22:27  北海小龙  阅读(295)  评论(0编辑  收藏  举报