注意可能出现重边……
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct Edge
{
int start;//边的起点
int end;//边的中点
int weight;//边的权值
}edges[150001];
int parent[501];//存储每个点的父节点
void MakeSet( int n)//初始化并查集
{
int i;
for(i=0; i<n; i++)
{
parent[i]=i;
}
}
int FindSet(int x)//查询并返回点x的父节点
{
if( x== parent[x])
{
return parent[x];
}
parent[x]=FindSet(parent[x]);//并查集路径压缩
}
bool Union( int x, int y)//合并
{
int rootX=FindSet(x);
int rootY=FindSet(y);
if( rootX != rootY )
{
parent[rootX]=rootY;
return 1;
}
return 0;
}
int Kruskal(int n)//n代表图具有n个点
{
int count=1;//记录生成树中的边数
int start ,end;
int i;
int max;//生成树的最大边权重
MakeSet(n);
for(i=0; count<=n-1; i++)
{
start=edges[i].start;
end=edges[i].end;
if( Union(start, end) )//如果两点不在一个集合,合并
{
if(max<edges[i].weight)
max=edges[i].weight;
count++;
}
}
return max;
}
bool Cmp(Edge a, Edge b)
{
return (a.weight<b.weight);
}
int main()
{
int Case, n;
int a[501][501];//图矩阵
int i, j, number=0;
scanf("%d",&Case);
while( Case-- )
{
number=0;
scanf("%d",&n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
scanf("%d",&a[i][j]);
}
for(i=0; i<n; i++)
for(j=0; j<i; j++)
{
if(a[i][j] != 0) //i和j间有边
{
edges[number].start=i;
edges[number].end=j;
edges[number].weight=a[i][j];
number++;
}
}
sort(edges, edges+number, Cmp);
cout<<Kruskal(n)<<endl;
}
}