实验三 贪心算法

实验三 贪心算法

迪杰斯特拉的贪心算法实现

优先队列等

1.实验目的

1、掌握贪心算法的基本要素 :最优子结构性质和贪心选择性质

2、应用优先队列求单源顶点的最短路径Dijkstra算法,掌握贪心算法。

2.实验环境

Java

3.问题描述

给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到所有其它各顶点的最短路长度。这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。

4.复杂度分析

Dijkstra算法的时间复杂度为O((m+n)logn),其中m是边的数量,n是顶点的数量。

5.代码实现

复制代码
package shiyan3_3;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.stream.Collectors;

public class DijkstraAlgorithm {

    public static void main(String[] args) throws IOException {
        runDijkstraAlgorithm("input.txt", "output.txt");
    }

    private static class Result {
        int dist;
        List<Integer> path;

        public Result(int dist, List<Integer> path) {
            this.dist = dist;
            this.path = path;
        }
    }

    public static void runDijkstraAlgorithm(String inputFile, String outputFile) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(inputFile));
        String[] input = reader.readLine().split(" ");
        int n = Integer.parseInt(input[0]);
        int m = Integer.parseInt(input[1]);

        List<Edge>[] graph = new List[n + 1];
        for (int i = 1; i <= n; i++) {
            graph[i] = new ArrayList<>();
        }

        for (int i = 0; i < m; i++) {
            input = reader.readLine().split(" ");
            int u = Integer.parseInt(input[0]);
            int v = Integer.parseInt(input[1]);
            int w = Integer.parseInt(input[2]);
            graph[u].add(new Edge(v, w));
        }
        reader.close();

        int s = 1;
        Result[] results = new Result[n + 1];
        PriorityQueue<Node> pq = new PriorityQueue<>();
        for (int i = 1; i <= n; i++) {
            if (i == s) continue;

            int[] dist = new int[n + 1];
            int[] pre = new int[n + 1];
            Arrays.fill(dist, Integer.MAX_VALUE);
            Arrays.fill(pre, -1);

            dist[s] = 0;
            pq.offer(new Node(s, 0));
            while (!pq.isEmpty()) {
                Node curr = pq.poll();
                if (curr.dist != dist[curr.u]) continue;
                for (Edge edge : graph[curr.u]) {
                    int v = edge.v;
                    int weight = edge.weight;
                    if (dist[v] > dist[curr.u] + weight) {
                        dist[v] = dist[curr.u] + weight;
                        pre[v] = curr.u;
                        pq.offer(new Node(v, dist[v]));
                    }
                }
            }

            List<Integer> path = new ArrayList<>();
            if (pre[i] != -1) getPath(i, pre, path);
            if (path.size() > 0) path.add(0, s);
            results[i] = new Result(dist[i], path);
        }

        PrintWriter writer = new PrintWriter(new FileWriter(outputFile));
        writer.println("起点\t终点\t最短路径\t\t\t最短路径长度");
        for (int i = 1; i <= n; i++) {
            if (i == s) continue;
            String res = s + "\t" + i + "\t";
            if (results[i] == null || results[i].path.size() == 0) {
                res += "NA\t\t\tNA";
            } else {
                String path = results[i].path.stream().map(Object::toString).collect(Collectors.joining("->"));
                int padding = 32 - path.length();
                if (padding > 0) path += String.format("%" + padding + "s", "");
                res += path + "\t" + results[i].dist;
            }
            writer.println(res);
        }
        writer.close();
        System.out.println("输出成功!");
    }

    private static void getPath(int u, int[] pre, List<Integer> path) {
        if (u == -1) return;
        getPath(pre[u], pre, path);
        path.add(u);
    }

    private static class Node implements Comparable<Node> {
        int u;
        int dist;

        public Node(int u, int dist) {
            this.u = u;
            this.dist = dist;
        }

        @Override
        public int compareTo(Node other) {
            return Integer.compare(this.dist, other.dist);
        }
    }

    private static class Edge {
        int v;
        int weight;

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

输入

运行

输出

相关推荐
lvwangshu10 分钟前
图论:LCA、树的直径、树的重心、二分图与 Tarjan 缩点
算法·图论
302wanger1 小时前
干与湿:AI 拿走脑力之后,人剩下什么
算法
计算机编程-吉哥2 小时前
脑肿瘤MRI智能识别系统:基于深度学习的像素级脑肿瘤语义分割平台【计算机毕业设计选题推荐】
人工智能·python·深度学习·算法·毕业设计·课程设计·大数据毕业设计选题推荐
用户204937554952 小时前
端侧语音部署踩坑:模型能跑不等于终端真的能用
后端·算法
shehuiyuelaiyuehao2 小时前
算法39,位运算,消失的两个数字
java·数据结构·算法
ZiLing2 小时前
2026 ROS 2 Lyrical 踩坑实录(一):编译与依赖——rosdep、现代 CMake 与 CMake 4.x
算法
Murphy_lx3 小时前
1124. 表现良好的最长时间段
c++·算法
aramae3 小时前
模拟实现strstr函数(C语言)
c语言·开发语言·算法
liliangcsdn3 小时前
因子权重矩阵处理-滞回缓冲带+降频稳定化动态重选
开发语言·python·算法
敲代码的嘎仔3 小时前
自己设计了一个兑换码算法:自增ID + Base32转码 + 按位加权签名 + 异或混淆,面试被追问细节时终于不用慌了
java·数据库·mysql·算法·微服务·面试·职场和发展