开始都没有意识到是求BST。后来到论坛看是求BST,Kruskal算法和prim算法,选择Kruskal算法。先用快排,再用并查集。
代码:
package Test1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Test24_1017 {
/**
* by qr jobdu 1017 2014-8-14
* @throws IOException
* Accepted 370MS
*/
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(
new InputStreamReader(System.in)));
//求BST,kruskal,快排
while (true) {
st.nextToken();
int n=(int)st.nval;
if(n==0)
break;
int m=n*(n-1)/2;
int road[][]=new int[m][3];
for(int i=0;i<m;i++){
for(int j=0;j<3;j++){
st.nextToken();
road[i][j]=(int)st.nval;
}
}
quicksort(road,0,m-1);//quick sort increasing from 0 to m(inclusive both)
int len=0,node1,node2,num=0; //num of edge
UnionFindSet ufs=new UnionFindSet(n+1);
for(int i=0;i<m;i++){
node1=road[i][0];
node2=road[i][1];
if(ufs.find(node1)!=ufs.find(node2)){
ufs.union(node1,node2);
len+=road[i][2];
num++;
}
if(num==(n-1))
break;
}
System.out.println(len);
}
}
private static void quicksort(int[][] arr, int i, int j) {
if(i==j) //只有一个元素 结束递归
return;
int len=arr[0].length;
int copyi=i; //保存指针
int copyj=j;
int pivot[]=new int[len]; //获取支点
for(int k=0;k<arr[0].length;k++)
pivot[k]=arr[i][k];
while(i<j){ //将比支点小的放到前面,比支点大的放到后面
while(i<j){
if(arr[j][2]<pivot[2]){
for(int k=0;k<arr[0].length;k++)
arr[i][k]=arr[j][k];
break;
}
j--;
}
while(i<j){
if(arr[i][2]>pivot[2]){
for(int k=0;k<arr[0].length;k++)
arr[j][k]=arr[i][k];
break;
}
i++;
}
}
for(int k=0;k<arr[0].length;k++) //支点放到相应位置
arr[i][k]=pivot[k];
//左右分别快排
if(copyi<i) //判断下
quicksort(arr,copyi,i-1); //left i??
if(copyj>j)
quicksort(arr,i+1,copyj); //right
}
}
class UnionFindSet{ //并查集类
int set[];
int size[];
UnionFindSet(){
}
UnionFindSet(int num){
set=new int[num];
size=new int[num];
for(int i=0;i<num;i++){
set[i]=i;
size[i]=1; //size数组为了平衡
}
}
void union(int i,int j){
int p=find(i);
int q=find(j);
if(p==q)
return;
if(size[p]<size[q]){ //平衡树大小
set[p]=q;
size[q]+=size[p];
}else{
set[q]=p;
size[p]+=size[q];
}
}
int find(int i){
while(i!=set[i]){
i=set[i];
}
return i;
}
}