洛谷 P2872 Building Roads S prim算法 java

洛谷 P2872 Building Roads S
这道题其实也是最小生成树的模板题,本人是用 prim 算法做的,题目给的是每个点的坐标,所以用两点的距离公式算出每两个点的距离,然后给每两个点都添加上边,因为题目有一些边已经连上了,所以再给图加上这些边(距离为 0),最后直接算最小生成树的边的和(weight 为 0 的边不影响结果)。

package 图论;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.PriorityQueue;
// 建边
class Edge implements Comparable<Edge> {
    int v;
    int w;
    double weight;

    public Edge(int v, int w, double weight) {
        this.v = v;
        this.w = w;
        this.weight = weight;
    }

    int either() {
        return v;
    }

    int other(int v) {
        if (this.v == v) {
            return w;
        }
        return this.v;
    }

    @Override
    public int compareTo(Edge o) {
        return Double.compare(this.weight, o.weight);
    }
}
// 建图
class EdgeWeightedGraph {
    int v;
    ArrayList[] adj;

    public EdgeWeightedGraph(int v) {
        this.v = v;
        adj = new ArrayList[v];
        for (int i = 0; i < v; i++) {
            adj[i] = new ArrayList();
        }
    }

    void addEdge(int v, int w, double weight) {
        Edge e = new Edge(v, w, weight);
        adj[v].add(e);
        adj[w].add(e);
    }

}

class LazyPrim {
    boolean[] marked;
    PriorityQueue<Edge> pq;
    ArrayDeque<Edge> queue;
    int v;

    public LazyPrim(EdgeWeightedGraph G) {

        this.v = G.v;
        marked = new boolean[v];
        pq = new PriorityQueue<>();
        queue = new ArrayDeque<>();

        visit(G, 0);

        while (! pq.isEmpty()) {
            Edge e = pq.poll();
            int v = e.either();
            int w = e.other(v);
            if (marked[v] == true && marked[w] == true) {
                continue;
            }
            queue.add(e);
            if (marked[v] == false) {
                visit(G, v);
            }
            if (marked[w] == false) {
                visit(G, w);
            }
        }
    }

    void visit(EdgeWeightedGraph G, int v) {
        marked[v] = true;
        for (Object o : G.adj[v]) {
            Edge e = (Edge)o;
            int w = e.other(v);
            if (marked[w] == false) {
                pq.offer(e);
            }
        }
    }
}

/**
 * @author wangshaoyu
 */
public class P2872BuildingRoads {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer st = new StreamTokenizer(br);
    static int nextInt() throws IOException {
        st.nextToken();
        return (int) st.nval;
    }
    static double nextDouble() throws IOException {
        st.nextToken();
        return st.nval;
    }

    public static void main(String[] args) throws IOException {
        int n = nextInt(); // 点数
        int m = nextInt(); // 边数
        EdgeWeightedGraph G = new EdgeWeightedGraph(n);

        int[][] xy = new int[n][2]; // 点的坐标
        for (int i = 0; i < n; i++) {
            xy[i][0] = nextInt();
            xy[i][1] = nextInt();
        }
        // 已经存在的边初始化为 0
        for (int i = 0; i < m; i++) {
            int v = nextInt() - 1;
            int w = nextInt() - 1;
            G.addEdge(v, w, 0);
        }
        // 每两个点添加一条边
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                double weight = Math.sqrt(Math.pow((xy[i][0] - xy[j][0]), 2) + Math.pow((xy[i][1] - xy[j][1]), 2));
                G.addEdge(i, j, weight);
            }
        }

        LazyPrim lp = new LazyPrim(G);

        double ans = 0;
        for (Edge e : lp.queue) {
            ans += e.weight;
        }
        System.out.printf("%.2f\n", ans);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值