畅通工程求最短公路长度

题目描述:

    某省调查乡村交通情况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任意两个村庄之间都可以实现公路交通(但不一定有直接的公路相连,只要间接通过公路可达即可),并要求铺设的公路总长度最短。请计算最小的公路总长度。

输入:

    测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N(<100);随后的N(N-1)/2行对应村庄之间的距离,每行给出一对正整数,分别是两个村庄的编号,以及两个村庄间的距离。为简单起见,村庄从1到N编号,当N为0时,输入结束,该用例不被处理。

输出:

    对每个测试用例,在1行里输出最短的公路总长度。

样例输入:

    3

    1 2 1

    1 3 2

    2 3 4

    4

    1 2 1

    1 3 4

    1 4 1

    2 3 3

    2 4 2

    3 4 5

    0

样例输出:

    3

    5

示例代码:

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            int node_cnt = scanner.nextInt();
            if (node_cnt==0){break;}
            Node nodes = new Node(node_cnt);
            int edge_cnt = node_cnt*(node_cnt-1)/2;
            Edge[] edges=new Edge[edge_cnt+1];
            for (int i=1;i<=edge_cnt;i++){
                int firstvillage = scanner.nextInt();
                int secondvillage = scanner.nextInt();
                int weight = scanner.nextInt();
                edges[i]=new Edge(firstvillage,secondvillage,weight);
            }

            //Kruskal算法生成MST
            Arrays.sort(edges,1,edge_cnt,new cmp());
            int length = 0;
            for (int j=1;j<=edge_cnt;j++){
                int fnode = edges[j].fnode;
                int snode = edges[j].snode;
                boolean isconnected = nodes.isConnected(fnode,snode);
                if (isconnected){continue;}
                else {
                    nodes.unionNodes(fnode,snode);
                    length+=edges[j].cost;
                }
            }
            System.out.println(length);
        }
    }
}


/*
* 为全体结点创建一个类,包含每个结点的根结点和此结点的重量
* */

public class Node {
    int[] nodes;//保存每个结点的根结点
    int size;
    int[] weights;//保存每个结点的重量,为将两个结点(集)合并提供依据
    public Node(int size){
        this.size = size;
        nodes = new int[size+1];
        weights = new int[size+1];
        for (int i=1;i<=size;i++){
            nodes[i] = i;
            weights[i]=1;
        }
    }

    public int findroot(int node){
        if (node==nodes[node]){return node;}
        else {
            int root = findroot(nodes[node]);
            nodes[node]=root;
            return root;
        }
    }

    public void unionNodes(int fnode,int snode){
        int froot = findroot(fnode);
        int sroot = findroot(snode);
        if (froot==sroot){return;}
        else {
            int fweight = weights[froot];
            int sweight = weights[sroot];
            if (fweight<=sweight){nodes[froot]=sroot;weights[sroot]+=fweight;}
            else{nodes[sroot]=froot;weights[froot]+=sweight;}
        }
    }

    public boolean isConnected(int fnode,int snode){return findroot(fnode)==findroot(snode);}

    public int setsNumber(int[] nodes){
        int cnt=0;
        for (int k=1;k<=size;k++){
            if (nodes[k]==k){cnt++;}
        }
        return cnt;
    }
}


/*
* 每条边为一个类,保存其权值和两个顶点
* */

public class Edge {
    int fnode,snode;
    int cost;
    public Edge(int fnode,int snode,int cost){
        this.fnode=fnode;
        this.snode=snode;
        this.cost=cost;
    }

}



/*按照权值将边进行排序*/

import java.util.Comparator;


public class cmp implements Comparator<Edge> {

    @Override
    public int compare(Edge o1, Edge o2) {
        if (o1.cost<o2.cost){return -1;}
        else {return 1;}
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值