目录

1 问题描述

2 解决方案

2.1 floyd算法解决

2.2 spfa算法解决

 


1 问题描述

问题描述

给定一个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
数据规模与约定

对于10%的数据,n = 2,m = 2。

对于30%的数据,n <= 5,m <= 10。

对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。


2 解决方案

2.1 floyd算法解决

使用floyd算法(ps:算法笔记_069:Floyd算法简单介绍(Java))求解本题的时间复杂度为O(n^3),下面代码在系统中测评分为40,原因:运行超时。以下代码仅供参考。

具体代码如下:

import java.util.Scanner;

public class Main {

    public void floyd(long[][] adjMatrix) {
for(int k = 0;k < adjMatrix.length;k++) {
for(int i = 0;i < adjMatrix.length;i++) {
for(int j = 0;j < adjMatrix.length;j++) {
if(adjMatrix[i][k] != Integer.MAX_VALUE && adjMatrix[k][j] != Integer.MAX_VALUE) {
if(adjMatrix[i][j] > adjMatrix[i][k] + adjMatrix[k][j])
adjMatrix[i][j] = adjMatrix[i][k] + adjMatrix[k][j];
}
}
}
}
for(int i = 1;i < adjMatrix.length;i++)
System.out.println(adjMatrix[0][i]);
} public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
if(n > 20000 || n < 1 || m > 200000 || m < 1)
return;
long[][] adjMatrix = new long[n][n];
for(int i = 0;i < n;i++) {
for(int j = 0;j < n;j++)
adjMatrix[i][j] = Integer.MAX_VALUE;
}
for(int i = 0;i < m;i++) {
int a = in.nextInt();
int b = in.nextInt();
int value = in.nextInt();
if(value > 10000 || value < -10000)
return;
adjMatrix[a - 1][b - 1] = value;
}
test.floyd(adjMatrix);
} }

2.2 spfa算法解决

使用spfa算法(PS:算法笔记_071:SPFA算法简单介绍(Java))求解本题的时间复杂度为O(m*E)(PS:其中E为给定边的数目,m为图中顶点进出链表的总次数,一般不大于2*n,n为图中总顶点数)。下面的给出的代码,在系统中测评分为70或者80分(PS:同样代码提交了两次,评分不一样),具体原因:运行超时。可能是Java语言编译时间没有C/C++那么快,所以不能在1s内完成。如果是楼主自己代码问题,还请路过同学不吝赐教啊~

具体代码如下:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner; public class Main { static class edge {
public int a; //边的起点
public int b; //边的终点
public int value; //边的权值 edge(int a, int b, int value) {
this.a = a;
this.b = b;
this.value = value;
}
} public void spfa(ArrayList<edge>[] listA, int n) {
long[] result = new long[n];
int[] num = new int[n];
boolean[] used = new boolean[n];
for(int i = 1;i < n;i++) {
result[i] = Integer.MAX_VALUE;
used[i] = false;
}
LinkedList<Integer> list = new LinkedList<Integer>();
list.add(0);
num[0] = 1;
used[0] = true;
while(list.size() > 0) {
int start = list.getFirst();
for(int i = 0, length = listA[start].size();i < length;i++) {
int b = listA[start].get(i).b;
int value = listA[start].get(i).value;
if(result[b - 1] > result[start] + value) {
result[b - 1] = result[start] + value;
if(!used[b - 1]) {
used[b - 1] = true;
list.add(b - 1);
num[b - 1]++;
if(num[b - 1] > n)
return;
}
}
}
list.removeFirst();
used[start] = false;
}
for(int i = 1;i < n;i++)
System.out.println(result[i]);
return;
} public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
if(n > 20000 || n < 1 || m > 200000 || m < 1)
return;
@SuppressWarnings("unchecked")
ArrayList<edge>[] listA = new ArrayList[n];
for(int i = 0;i < n;i++)
listA[i] = new ArrayList<edge>();
for(int i = 0;i < m;i++) {
int a = in.nextInt();
int b = in.nextInt();
int value = in.nextInt();
if(value > 10000 || value < -10000)
return;
listA[a - 1].add(new edge(a, b, value));
}
test.spfa(listA, n);
}
}

最新文章

  1. Mac下的Maven配置
  2. 6.Counting Point Mutations
  3. javascript介绍
  4. 带清空按钮的EditText
  5. (lleetcode)Single Number
  6. 在block中使用self
  7. javascript之小积累-.-添加form表单查询的enter键支持
  8. js实现hash
  9. uva494 Kindergarten Counting Game
  10. Swift实战-小QQ(第2章):QQ侧滑菜单
  11. Form_通过Custom.pll新增菜单项(案例)
  12. 我对CONTAINING_RECORD宏的详细解释
  13. IDE改为AHCI后系统无法启动的解决办法
  14. Vivado Launching SDK &quot;Importing Hardware Specification&quot; error的解决方法
  15. UVa 11063 - B2-Sequence
  16. Bestcoder #80
  17. MySQL的外键,修改表,基本数据类型,表级别操作,其他(条件,通配符,分页,排序,分组,联合,连表操作)
  18. 生鲜配送管理系统_升鲜宝V2.0 小标签打印功能【代配送商品打印小标签功能】说明_15382353715
  19. FileUpload上传
  20. oracle数据库误删的表以及表中记录的恢复

热门文章

  1. Bzoj2721 [Violet]樱花(筛法)
  2. POJ 3660 Cow Contest (dfs)
  3. HDU 6373 Pinball
  4. coreseek mmseg分词配置和创建
  5. 【POJ 3784】 Running Median (对顶堆)
  6. Java中的对象池技术
  7. Thupc2017&quot;礼&quot;?
  8. C++中的读入输出优化及清新脱俗的宏命令
  9. Educational Codeforces Round 41 (Rated for Div. 2) ABCDEF
  10. 【数学期望】hdu5984 Pocky