稍微改一下1017题的代码,在读入边时就合并点,相当于为树的边,再用Kruskal的思想即可
代码:
package Test1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Test38_1028 {
/**
* by qr jobdu 1028 2014-8-21
*
* @throws IOException
*/
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(
new InputStreamReader(System.in)));
while (true) {
st.nextToken();
int n = (int) st.nval;
if (n == 0)
break;
int m=n*(n-1)/2;
UnionFindSet ufs=new UnionFindSet(n+1);
int num=0;//num of edge
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;
}
int n1=road[i][0];
int n2=road[i][1];
st.nextToken();
int flag=(int)st.nval;
if(flag==1)
if(ufs.find(n1)!=ufs.find(n2)){
ufs.union(n1,n2);
num++;
}
}
quicksort(road,0,m-1);//quick sort increasing from 0 to m(inclusive both)
int len=0,node1,node2;
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;
}
}