问题
问题描述
给定一个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分
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);
}
}
}