首页 > 试题广场 >

还是畅通工程

[编程题]还是畅通工程
  • 热度指数:14509 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
    某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。

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


输出描述:
    对每个测试用例,在1行里输出最小的公路总长度。
示例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
为什么Prime算法过不了呢


import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;

class Edge{
    int v1;
    int v2;
    int cost;

    public Edge(int v1, int v2, int cost) {
        this.v1 = v1;
        this.v2 = v2;
        this.cost = cost;
    }
}
class ListNode{
    public int v;
    public int cost;
    ListNode next;

    public ListNode(int v, int cost) {
        this.v = v;
        this.cost = cost;
    }

    public ListNode() {
    }
}

class Graph{
    ListNode[] graph;

    int size;

    public Graph(int size,Edge[] edges) {
        this.size = size;
        graph=new ListNode[size+1];
        Arrays.fill(graph,new ListNode());
        for (Edge e:edges)
        {
            ListNode n1 = new ListNode(e.v1, e.cost);
            ListNode n2 = new ListNode(e.v2, e.cost);
            n2.next=graph[e.v1].next;
            graph[e.v1].next=n2;

            n1.next=graph[e.v2].next;
            graph[e.v2].next=n1;
        }

    }

    public int prime(int start)
    {
        int []cost=new int[size+1];
        int []visited=new int[size+1];

        Arrays.fill(cost,Integer.MAX_VALUE);
        Arrays.fill(visited,0);

        cost[start]=0;
        visited[start]=1;
        for (ListNode p=graph[start].next;p!=null;p=p.next)
        {
            cost[p.v]=p.cost;
        }

        int sumCost=0;
        for (int i = 1; i < size; i++) {

            int minIndex=-1;
            int minCost=Integer.MAX_VALUE;

            for (int j = 1; j < size+1; j++) {
                if (visited[j]==0 && cost[j]<minCost)
                {
                    minCost=cost[j];
                    minIndex=j;
                }
            }

            visited[minIndex]=1;
            sumCost+=minCost;
            ListNode node = graph[minIndex].next;
            while (node!=null)
            {
                if (visited[node.v]==0 && cost[node.v]>node.cost)
                {
                    cost[node.v]=node.cost;
                }
                node=node.next;
            }
        }
        return sumCost;

    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext())
        {
            int size = scanner.nextInt();
            if (size==0)
                break;
            Edge[] edges = new Edge[size * (size - 1) / 2];
            for (int i = 0; i < size*(size-1)/2; i++) {
                int v1 = scanner.nextInt();
                int v2 = scanner.nextInt();
                int cost = scanner.nextInt();
                edges[i]=new Edge(v1,v2,cost);
            }
            Graph g = new Graph(size,edges);
            System.out.println(g.prime(1));
        }
    }
}


编辑于 2024-03-22 14:00:40 回复(1)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class Main {
    static class edge {
        int a;
        int b;
        int length;

        public edge(int a, int b, int length) {
            this.a = a;
            this.b = b;
            this.length = length;
        }

    }

    static int[] parent = new int[100];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s;
        while ((s = br.readLine()) != null) {
            if (s.equals("0")) break;
            int N = Integer.parseInt(s);
            ArrayList<edge> list = new ArrayList<>();
            for (int i = 0; i < N * (N - 1) / 2; i++) {
                String[] str = br.readLine().split(" ");
                edge e = new edge(Integer.parseInt(str[0]), Integer.parseInt(str[1]), Integer.parseInt(str[2]));
                list.add(e);
                //升序
                list.sort((o1, o2) -> o1.length - o2.length);
            }
            for (int i = 0; i < 100; i++) { //每个节点的父节点都是自身(还未开始连通)
                parent[i] = -1;
            }
            //初始化结束

            int sum = 0;
            for (int i = 0; i < list.size(); i++) {
                edge e = list.get(i);
                if (FindRoot(e.a) != FindRoot(e.b)) {   //若不在一个集合中,则需要连接
//                    parent[e.a]=e.b;  //错了,不能这么写,数组会被覆盖
                    parent[FindRoot(e.a)] = FindRoot(e.b);  //表面上连接的不是当前的边,实际上已经做过路径压缩
                    sum += e.length;
                }
            }

            System.out.println(sum);

        }
    }

    private static int FindRoot(int t) {
        if (parent[t] == -1) return t;
        else {
            int temp = FindRoot(parent[t]);   //路径压缩
            parent[t] = temp;
            return temp;
        }
    }


}


发表于 2021-04-11 21:53:14 回复(0)