poj_2485_kruskal

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

题目描述:

求最小生成树中的最大边权值。最近prim和dij写恶心了,这个就用kruskal做吧。poj_2485_kruskal

思路:

水题。就是kruskal选择最小生成树边,最后选中的那条边,即为最小生成树的最大权值的边。(如果用prim的话,选入点的时候记录最大边权值就行)。时间复杂度O(eloge)。

代码:

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

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

int G[N][N];
int set[N];
EDGE edge[N*(N-1)/2];

int partition(int low, int high)
{
   EDGE tmp = edge[low];
  while(low<high)
   {
     while(low<high &&edge[high].weight >= tmp.weight)
        high --;
     if(low < high)
        edge[low++] = edge[high];
     while(low < high &&edge[low].weight <= tmp.weight)
        low ++;
     if(low < high)
        edge[high--] = edge[low];
   }
   edge[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 k;
   int n,i,j, max;
   int num;
  
  scanf("%d",&num);
  while(num>0)
   {
      k = 1;
      scanf("%d",&n);
      for(i=1;i<=n;i++)
         for(j=1;j<=n;j++)
         {
            scanf("%d",&G[i][j]);
            if(i<j)
            {
               edge[k].s = i;
               edge[k].e = j;
               edge[k++].weight = G[i][j];
            }
         }
      //kruskal
      //make set 
      for(i=1;i<=n;i++)
         set[i] = i;
      //sort edge
      sort(1,k-1);
      //select edge
      for(i=1;i<=k-1;i++)
         if(find_set(edge[i].s) != find_set(edge[i].e))
         {
             max = edge[i].weight;
             union_set(edge[i].s, edge[i].e);
         }
         
      printf("%d\n",max);
      num --;
   }
   //system("pause");
   return 0;
}

 

原创粉丝点击