COMP3023 Design and Analysis of Algorithms

 一个学生作业,拿去吧,直接用

package com.xxl.job.executor.service.jobhandler;

import java.io.*;
import java.util.*;

public class DAG {
    public static void main(String[] args) throws IOException {
        // 读取输入文件 in.txt
        String inputInFile = "C:\\Users\\Administrator\\Desktop\\in.txt";
        BufferedReader reader = new BufferedReader(new FileReader(inputInFile));
        int fileN = Integer.parseInt(reader.readLine().trim());
        int[] uvs = Arrays.stream(reader.readLine().split("\\s+"))
                .mapToInt(Integer::parseInt).toArray();
        int u = uvs[0], v = uvs[1];
        int[] weights = Arrays.stream(reader.readLine().split("\\s+"))
                .mapToInt(Integer::parseInt).toArray();
        // 读取邻接矩阵并构建邻接表
        List<List<Integer>> listArrayList = new ArrayList<>();
        for (int i = 0; i < fileN; i++) {
            listArrayList.add(new ArrayList<>());
            int[] rows = Arrays.stream(reader.readLine().split("\\s+"))
                    .mapToInt(Integer::parseInt).toArray();
            for (int j = 0; j < fileN; j++) {
                if (rows[j] == 1) listArrayList.get(i).add(j);
            }
        }
        reader.close();
        // 拓扑排序
        List<Integer> topOrders = kahnTopoLogicalSort(listArrayList, fileN);
        // 动态规划计算最大路径
        long[] dps = new long[fileN];
        Arrays.fill(dps, Long.MIN_VALUE);
        dps[u] = weights[u];
        int[] prev = new int[fileN];
        Arrays.fill(prev, -1);
        for (int node : topOrders) {
            if (dps[node] == Long.MIN_VALUE) continue;
            for (int neighbor : listArrayList.get(node)) {
                if (dps[neighbor] < dps[node] + weights[neighbor]) {
                    dps[neighbor] = dps[node] + weights[neighbor];
                    prev[neighbor] = node;
                }
            }
        }
        // 输出结果到out.txt文件中
        String outputToOutFile = "C:\\Users\\Administrator\\Desktop\\out.txt";
        BufferedWriter writer = new BufferedWriter(new FileWriter(outputToOutFile));
        if (dps[v] == Long.MIN_VALUE) {
            writer.write("路径不存在,请检查后处理");
        } else {
            writer.write(dps[v] + "\n");
            List<Integer> paths = reconstructPath(prev, u, v);
            for (int i = 0; i < paths.size(); i++) {
                writer.write(paths.get(i) + (i < paths.size()-1 ? " " : ""));
            }
        }
        writer.close();
    }

    // Kahn算法 -- 拓扑排序
    private static List<Integer> kahnTopoLogicalSort(List<List<Integer>> intersection, int n) {
        // 初始化所有节点的入度数组,用于后续的拓扑排序
        int[] degrees = new int[n];
        // 遍历邻接表,统计每个节点的入度
        for (List<Integer> list : intersection) {
            for (int node : list) {
                degrees[node]++;
            }
        }
        // 使用队列来存储所有入度为0的节点,作为拓扑排序的起始节点
        Queue<Integer> q = new LinkedList<>();
        // 将所有入度为0的节点添加到队列中
        for (int i = 0; i < n; i++) {
            if (degrees[i] == 0) {
                q.add(i);
            }
        }
        // 用于存储拓扑排序结果的列表
        List<Integer> order = new ArrayList<>();
        // 当队列不为空时,进行拓扑排序
        while (!q.isEmpty()) {
            // 从队列中取出一个节点
            int u = q.poll();
            // 将该节点添加到拓扑排序结果中
            order.add(u);
            // 遍历该节点的所有邻接节点,并减少它们的入度
            for (int v : intersection.get(u)) {
                // 如果节点的入度减为0,则将其添加到队列中
                if (--degrees[v] == 0) {
                    q.add(v);
                }
            }
        }
        // 返回拓扑排序结果
        return order;
    }
    private static List<Integer> reconstructPath(int[] prev, int u, int v) {
        // 创建一个列表用于存储从起点到终点的路径
        List<Integer> paths = new ArrayList<>();
        // 从终点v开始,通过prev数组回溯到起点,将路径中的顶点添加到path列表中
        for (int i = v; i != -1; i = prev[i]) {
            paths.add(i);
        }
        // 将路径反转,以便从起点到终点表示路径
        Collections.reverse(paths);
        // 如果路径的起点是u,则返回这条路径;否则返回空列表,表示没有找到有效的路径
        return paths.get(0) == u ? paths : Collections.emptyList();
    }
}

 in.txt文件内容

4
0 3
3 2 1 4
0 1 1 1
0 0 0 1
0 0 0 1
0 0 0 0

 (大环境真可怕,自己卷自己)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大小先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值