题目描述:
求最小生成树中的最大边权值。最近prim和dij写恶心了,这个就用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);