蓝桥杯--最短路问题

问题

问题描述

  给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

输入格式

  第一行两个整数n, m。

  接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

输出格式

  共n-1行,第i行表示1号点到i+1号点的最短路。

样例输入

  3 3
  1 2 -1
  2 3 -1
  3 1 2

样例输出

  -1
  -2

解释

  我自己只得了50分。我的思路就是先利用Floyd算法求得到各个结点到其他节点的最短路径,储存在 path 中,然后根据 A 联合输出最短路径权重。


Floyd算法,自我理解,链接如下:
https://blog.youkuaiyun.com/Bkhole/article/details/122022656


代码

100分

蓝桥杯算法训练 最短路java—作者 :陌丶尘

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

public class Main {
    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    public static int nextInt() throws IOException{
        in.nextToken();
        return (int)in.nval;
    }
    static int[] leng;
    public static void main(String[] args) throws IOException{
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        int n = nextInt();
        int m = nextInt();
        List<node> list[] = new ArrayList[n];
        for(int i=0;i<n;i++)//初始化
        {
            list[i] = new ArrayList<>();
        }
        leng = new int[n];
        boolean[] judge = new boolean[n];
        for(int i=1;i<n;i++)
        {
            leng[i] = Integer.MAX_VALUE;
        }
        for(int i=0;i<m;i++)
        {
            int u = nextInt();
            int v = nextInt();
            int l = nextInt();
            list[u-1].add(new node(v-1,l));
        }
        Queue<Integer> q1 = new ArrayDeque<Integer>();
        q1.add(0);
        while(!q1.isEmpty())
        {
            int x = q1.poll();
            judge[x] = false;
            for(int i=0;i<list[x].size();i++)
            {
                int index = list[x].get(i).x;
                int length = list[x].get(i).leng;
                if(leng[index]>leng[x]+length)
                {
                    leng[index] = leng[x]+length;
                    if(!judge[index])
                    {
                        q1.add(index);
                        judge[index] = true;
                    }
                }
            }
        }
        for(int i=1;i<n;i++)
        {
            out.println(leng[i]);
        }
        out.flush();
    }
    static class node{
        int x;
        int leng;
        public node(int x,int leng)
        {
            this.x = x;
            this.leng = leng;
        }
    }

}


50分


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    static int inf = 100000;
    static Set<List> set ;
    static int[][] A = null;
    static int[][] path = null;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Users\\Lenovo\\Desktop\\temp.txt"))));
        String[] str = br.readLine().split(" ");
        int n = Integer.valueOf(str[0]);
        int m = Integer.valueOf(str[1]);

        A = new int[n][n];
        path = new int[n][n];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                path[i][j] = -inf;
                A[i][j] = inf;
                if (i == j) {
                    A[i][j] = 0;
                }
            }
        }
        for (int i = 0; i < m; i++) {
            str = br.readLine().split(" ");
            Integer u = Integer.valueOf(str[0]);
            Integer v = Integer.valueOf(str[1]);
            Integer power = Integer.valueOf(str[2]);
            A[u-1][v-1] = power;
        }

        Floyd(A,path);

        for (int i = 1; i < n; i++) {
            function(0,i);
        }
    }

    static void Floyd(int[][] A,int[][] pathB){
        for (int k = 0; k < A.length; k++) {
            for (int i = 0; i < A.length; i++) {
                for (int j = 0; j < A.length; j++) {
                    if ((i == j || i == k || j == k))
                        continue;
                    if (A[i][j] > A[i][k]+A[k][j]) {
                        A[i][j] = A[i][k]+A[k][j];
                        pathB[i][j] = k;
                    }
                }
            }
        }
    }

    static void function(int i,int j){
        set = new HashSet<>();
        findRoad(i,j);
        int count = 0;
        for (List<Integer> list : set) {
            Integer u = list.get(0);

            Integer v = list.get(1);

            count += A[u][v];
        }
        System.out.println(count);
    }

    static void findRoad(int i,int j){
        if (path[i][j] == -inf) {
            ArrayList<Integer> list = new ArrayList<>();
            list.add(i);
            list.add(j);
            set.add(list);
        }else {
            int mid = path[i][j];
            findRoad(i,mid);
            findRoad(mid,j);
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值