面试常规算法复习(最小生成树)

两种常规的算法。

package com.company;

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

class Edge {
    int a, b, w;
    Edge(int a, int b, int w){
        this.a = a;
        this.b = b;
        this.w = w;
    }
}

public class Main {
    public static void main(String[] args) {
        int w[][] = new int[1005][1005];
        int INF = 0x3f3f3f3f;
//        System.out.println(INF);
        int n, m;
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();

        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= n; j++)
                if (i != j)w[i][j] = INF;
                else w[i][j] = 0;
        }
        for (int i = 1; i <= m; i++){
            int u, v, W;
            u = in.nextInt();
            v = in.nextInt();
            W = in.nextInt();
            w[u][v] = Math.min(w[u][v], W);
            w[v][u] = Math.min(w[v][u], W);
        }
//        int s = in.nextInt();
//        int e = in.nextInt();
//        kruskal(n, w);
        prime(n, w);
    }

    public static int finds(int n, int f[]){
        return f[n] == n?n:(f[n] = finds(f[n], f));
    }

    //将所有的边排序,从最小的边开始,将两点加入集合,如果在同一集合那么就不记录
    //集合通过并查集维护
    public static void kruskal(int n, int w[][]){
        int INF = 0x3f3f3f3f;
        Comparator<Edge> comparator = new Comparator<Edge>() {
            @Override
            public int compare(Edge o1, Edge o2) {
                return o1.w-o2.w;
            }
        };
        Queue<Edge> q = new PriorityQueue<Edge>(comparator);
        for (int i = 1; i <= n; i++){
            for (int j = i+1; j <= n; j++){
                if (w[i][j] != INF){
                    q.add(new Edge(i, j, w[i][j]));
                }
            }
        }
        int f[] = new int[1005];
        for (int i = 1; i <= n; i++){
            f[i] = i;
        }
        int sum = 0;
        while (!q.isEmpty()){
            Edge x = q.poll();
            int a = finds(x.a, f);
            int b = finds(x.b, f);
            if (a != b){
                f[a] = b;
                sum += x.w;
            }
        }
        System.out.println(sum);
    }
    //思想类似与迪杰斯特拉算法。。。
    //选择一个开始点,选择与开始点最短距离的点,将其连接记录,后面重复上次操作就可以了。
    //注意在那个距离更新不是松弛操作。

    public static void prime(int n, int w[][]){
        int d[] = new int[1005];
        boolean vis[] = new boolean[1005];
        int INF = 0x3f3f3f3f;
        for(int i = 1; i <= n; i++)d[i] = (i==1)?0:INF;
        int sum = 0;
        for(int i = 1; i <= n; i++){
            int x=1, m=INF;
            for(int j = 1; j <= n; j++){
                if(!vis[j] && m > d[j]){
                    x = j;
                    m = d[j];
                }
            }
            vis[x] = true;
            sum += m;
//            System.out.println(m);
            for (int j = 1; j <= n; j++){
                if (!vis[j])d[j] = Math.min(d[j], w[j][x]);
            }
        }
        System.out.println(sum);
    }

}

原文地址:https://www.cnblogs.com/liuqiyu/p/11988499.html

时间: 2024-10-05 08:20:50

面试常规算法复习(最小生成树)的相关文章

面试高级算法梳理笔记

面试高级算法梳理笔记 1.1 说明 本篇为<挑战程序设计竞赛(第2版)>读书笔记系列,旨在: 梳理算法逻辑 探索优化思路 深入代码细节 1.2 目录 原文首发于个人博客Jennica.Space,按算法难度划分为初中高三个级别,详细目录及链接如下: 初级篇 穷竭搜索 贪心 动态规划 数据结构 图论 数论 中级篇 二分搜索 常用技巧 数据结构(二) 动态规划(二) 网络流 计算几何 高级篇 数论(二) 博弈论 图论(二) 常用技巧(二) 智慧搜索 分治 字符串 1.3 题解 配套习题及详解同步发

算法复习计划

写在前面 随着四月的到来, 离省选越来越近了. 从NOIP到现在, 学到了很多很多东西, 有的学的比较深入, 有的只是略知一二 从明天开始, 进行针对省选的算法复习计划. 省选前完成. 重点是对算法的理解和应用, 还会注重模板习惯的养成 计划内容 1. 数据结构 一直觉得我数据结构学的还可以, 不过列出来发现会的也没多少. 少就少吧, 省选够用就行... 线段树 树状数组 并查集 哈希表 STL treap splay 树链剖分 主席树(可忽略) 字符串(KMP, 后缀数组) 2. 图论 掌握经

算法复习-研一上

算法复习  包含主题: 贪心算法 , 分治法,动态规划,回溯法,分支限界,线性规划 关键词:最优子结构 Q:贪心与动态规划中间的联系和区别 p93 后面总结 (背部问题,0-1背包问题) 递归分治算法 基本思想:将一个大的问题分成若干小的子问题问题,分而治之 一般步骤:1.分解将原问题分为若干规模小,相互独立与原问题形式相同的问题   2.求解,求解各个子问题,当问题被划分的足够小的时候,就能很容易求解     3.合并,将子问题逐层合并,得到最后的解 经典问题 二分搜索: 合并排序(将想要排序

程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦

程序员面试.算法研究.编程艺术.红黑树.数据挖掘5大系列集锦

C语言排序算法复习

排序算法有很多种,这里在复习和分析的基础上,做一个自己的总结: 首先要知道有哪些排序算法,google一下,有云C语言7大经典排序算法(也有8大).主要包括冒泡排序,快速排序,选择排序,插入排序,希尔排序,归并排序,堆排序,8大的还有基数排序.各有各的版本,代码写法也各不相同.所以这里以整理思路为先,代码只是作为自己的一个备份. 搞清楚的概念:稳定排序和不稳定排序,就看序列中两个值相等的数,排完序之后的相对位置是否改变,如果改变了就不稳定. 内部排序和外部排序,只用到内存即可完成排序的就叫内部排

普利姆算法(最小生成树)

int prim(){ int minid, i, j; double mincost; for(i = 2; i <= n; i ++){ lowcost[i] = map[1][i]; } lowcost[1] = -1; for(i = 2; i <= n; i ++){ mincost = INF; minid = 0; for(j = 2; j <= n; j ++){ if(lowcost[j] < mincost && lowcost[j] >

Prime算法求最小生成树 (邻接表)

/* Name: Prime算法求最小生成树 (邻接表) Copyright: Author: 巧若拙 Date: 25/11/14 13:38 Description: 实现了 Prime算法求最小生成树 (邻接表)的普通算法和最小堆优化算法. */ #include<stdio.h> #include<stdlib.h> #define MAX 2000   //最大顶点数量 #define INFINITY 999999   //无穷大 typedef int VertexT

十大基础实用算法之迪杰斯特拉算法、最小生成树和搜索算法

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离). 初始时,S中只有起点s:U中是除s之外的顶点,并且U中顶点的路径是"起点s

重拾算法(5)——最小生成树的两种算法及其对比测试

重拾算法(5)——最小生成树的两种算法及其对比测试 什么是最小生成树 求解最小生成树(Minimum Cost Spanning Tree,以下简写做MST)是图相关的算法中常见的一个,用于解决类似如下的问题: 假设要在N个城市之间建立通信联络网,那么连通N个城市只需N-1条线路.这时自然会考虑这样一个问题:如何在最节省经费的前提下建立这个通信网. 在任意两个城市间都可以设置一条线路,相应地都要付出一定的经济代价.N个城市之间最多可能设置N(N-1)/2条线路,那么如何在这些线路中选择N-1条,