题目1017:还是畅通工程(2006年浙江大学计算机及软件工程研究生机试真题)

本文介绍了一道关于计算最小公路总长度的问题,通过构建最小生成树来实现任意两村庄间的道路连接,同时确保公路总长度最短。文章提供了一个使用Java实现的具体案例,包括输入输出说明、核心算法步骤及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目1017:还是畅通工程

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:2998

解决:1498

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

    测试输入包含若干测试用例。每个测试用例的第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{
 
    static int Tree[] = new int[101];
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
         
        while( scanner.hasNext() ){
            int n = scanner.nextInt();
            if(n == 0) break;
            Arrays.fill(Tree, -1);
            int k = n*(n-1)/2;
             
            Edge edges[] = new Edge[k+1];
            for (int i = 1; i <= k; i++) {
                edges[i] = new Edge();
                edges[i].a = scanner.nextInt();
                edges[i].b = scanner.nextInt();
                edges[i].cost = scanner.nextInt();
            }
             
            quickSortEdgeByCost(1,k,edges);
             
            int ans = 0;
            for (int i = 1; i <= k; i++) {
                int a = edges[i].a;
                int b = edges[i].b;
                int cost = edges[i].cost;
                 
                a = findRoot(a);
                b = findRoot(b);
                if(a != b){
                    Tree[a] = b;
                    ans += cost;
                }
            }
            System.out.println(ans);
             
        }
    }
     
     
    public static class Edge{
        int a;
        int b;
        int cost;
         
    }
     
    public static int findRoot(int x){
        if(Tree[x] == -1) return x;
        else{
            int tmp = findRoot(Tree[x]);
            Tree[x] = tmp;
            return tmp;
        }
    }
     
    public static void quickSortEdgeByCost(int low, int high, Edge edges[]) {
        int key = edges[low].cost;
        int begin = low;
        int end = high;
         
        while(low < high){
            while(edges[low].cost <= key && low < high){
                low ++;
            }
            while(edges[high].cost > key && low < high){
                high--;
            }
             
            if(low < high){
                Edge temp = edges[low];
                edges[low] =edges[high];
                edges[high] = temp;
            }
             
        }
         
         
        if(edges[low].cost < key){
            Edge temp = edges[low];
            edges[low] =edges[begin];
            edges[begin] = temp;
        }
         
        if(begin < low - 1){
            quickSortEdgeByCost(begin, low-1, edges);
        }
        if(end > low){
            quickSortEdgeByCost(low, end, edges);
        }
    }
 
}
 
/**************************************************************
    Problem: 1017
    User: yihukurama
    Language: Java
    Result: Accepted
    Time:590 ms
    Memory:86000 kb
****************************************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值