poj 1251_kruskal

来源:互联网 发布:java通过ip获取地区 编辑:程序博客网 时间:2024/06/14 09:30

题目描述:

求保持森林中每个村子都有道路相通,且维修所需要的最少money。

解题思路:

水题。kruskal,最小生成树问题。和原算法没神马出入。输入的时候注意下就好了(用scanf("%s")省点劲)。

代码:

#include <stdio.h>
#include <stdlib.h>
#define N 100

typedef struct{
   int s;
   int e;
   int weight;
}ROAD;

ROAD roads[N];
int set[N];

int partition(int low, int high)
{
   ROAD tmp = roads[low];
  while(low<high)
   {
     while(low<high &&roads[high].weight >= tmp.weight)
        high --;
     if(low < high)
        roads[low++] = roads[high];
     while(low < high &&roads[low].weight <= tmp.weight)
        low ++;
     if(low < high)
        roads[high--] = roads[low];
   }
   roads[low] = tmp;
   return low;
}
void sort(int low, int high)
{
   int index;
   if(low <high)
   {
       index = partition(low, high);
       sort(low,index-1);
       sort(index+1,high);
   }
}
int find_set(int i)
{
   if(set[i]!=i)
     set[i] = find_set(set[i]);
   return set[i];
}
void union_set(int i, int j)
{
   int i1 = find_set(i);
   int j1 = find_set(j);
   set[i1] = set[j1];
}
main()
{
   int n,len,r,sum,i,j,k;
   char src[10],end[10];
  
  scanf("%d",&n);
   while(n!=0)
   {
      r = 1;
      sum = 0;
      for(i=1;i<n;i++)
      {
         scanf("%s%d",src,&k);
         for(j=1;j<=k;j++)
         {
            scanf("%s%d",end, &len);
            roads[r].s = src[0] - 'A'+1;
            roads[r].e = end[0] - 'A'+1;
            roads[r++].weight = len;
         }
      }
      len = r-1;// len条路径
      sort(1,len);
      //make set
      for(i=1;i<=n;i++)
         set[i] = i;
      for(i=1;i<=len;i++)
         if(find_set(roads[i].s) != find_set(roads[i].e))
         {
            sum += roads[i].weight;
            union_set(roads[i].s,roads[i].e);
         }
      printf("%d\n",sum);
      scanf("%d",&n);
   }
   //system("pause");
   return 0;
}

原创粉丝点击