HDU 2544 最短路 [最短路]

本文深入探讨了最短路径算法,包括Dijkstra算法和Bellman-Ford算法的实现与优化,通过C++和Java代码详细解释了不同算法的时间复杂度和应用场景。

原题
#Description
就是最短路
#Algorithm
##Dijkstra
我就用最水的 未加优化的做了一下 理论时间复杂度O(V^2)
V为顶点数
后来想想光一开始赋值INF就用了V^2实在不划算
就做了个hasCost的优化,空间换时间,不过也没有快多少
还是要学优先队列的优化啊
V2.1用了优先队列优化 不过比V1.1还慢 = =
不过好歹会用了JAVA的pq
##Bellman-Ford
V3.0
理论上最慢 实际上最快 = =
#Code
##V3.0
###C++

#include <iostream>
#include <algorithm>
#include <climits>
#include <cstdio>
using namespace std;
struct Edge
{
  int from, to, cost;
  Edge(){}
  Edge(int a, int b, int c) : from(a), to(b), cost(c) {}
};
const int INF = INT_MAX / 2;
const int maxn = 1e5 + 9;
const int maxm = 1e6 + 9;
int d[maxn]; //花费
Edge g[2 * maxm]; //图
int n;
int m;
void solve()
{
  int g_size = 0;
  for (int i = 0; i < m; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    a--;
    b--;
    g[g_size++] = Edge(a, b, c);
    g[g_size++] = Edge(b, a, c);
  }
  fill(d, d + n, INF);
  d[0] = 0;
  for (;;) {
    bool update = false;
    for (int i = 0; i < g_size; i++) {
      Edge e = g[i];
      if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost) {
        d[e.to] = d[e.from] + e.cost;
        update = true;
      }
    }
    if (!update) break;
  }
  cout << d[n - 1] << endl;
}
int main()
{
 // freopen("in.txt", "r", stdin);
  for (;;) {
    scanf("%d%d", &n, &m);
    if (n == 0 && m == 0) break;
    solve();
  }

}

###JAVA

import java.util.Scanner;
class Edge {
  int from;
  int to;
  int cost;
  Edge(int a, int b, int c) {
    from = a;
    to = b;
    cost = c;
  }
}
public class Main {
  public static void main(String[] args) {
    final int INF = Integer.MAX_VALUE / 2;
    Scanner cin = new Scanner(System.in);
    for (;;) {
      int n = cin.nextInt();
      int m = cin.nextInt();
      if (n == 0) break;
      int[] d = new int[n];
      for (int i = 0; i < n; i++) {
        d[i] = INF;
      }
      Edge[] g = new Edge[2 * m];
      for (int i = 0; i < m; i++) {
        int a = cin.nextInt() - 1;
        int b = cin.nextInt() - 1;
        int c = cin.nextInt();
        g[i] = new Edge(a, b, c);
        g[i + m] = new Edge(b, a, c);
      }
      d[0] = 0;
      for (;;) {
        boolean update = false;
        for (Edge e : g) {
          if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost) {
            d[e.to] =  d[e.from] + e.cost;
            update = true;
          }
        }
        if (!update) break;
      }
      System.out.println(d[n - 1]);
    }
  }
}

##V2.0
###C++

#include <iostream>
#include <climits>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
const int INF = INT_MAX;
const int MAXN = 200 + 9;
struct Edge
{
  Edge(int a, int b) : to(a), cost(b) {}
  int to, cost;
};
struct P
{
  int dis;
  int i;
  P(int a, int b) : dis(a), i(b) {}
};
struct comp
{
  bool operator() (P a, P b)
  {
    return a.dis < b.dis;
  }
};
int d[MAXN];
int n, m;
void solve()
{
  priority_queue<P, vector<P>, comp> pq;
  vector<Edge> g[MAXN];
  for (int i = 0; i < m; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    a--;
    b--;
    g[a].push_back(Edge(b, c));
    g[b].push_back(Edge(a, c));
  }
  fill(d, d + n, INF);
  d[0] = 0;
  pq.push(P(0, 0));
  while(!pq.empty()) {
    P p = pq.top();
    pq.pop();
    int v = p.i;
    if (d[v] < p.dis) continue;
    for (int i = 0; i < g[v].size(); i++) {
      Edge e = g[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        pq.push(P(d[e.to], e.to));
      }
    }
  }
  cout << d[n - 1] << endl;
}
int main()
{
//  freopen("in.txt", "r", stdin);
  for (;;) {
    scanf("%d%d", &n, &m);
    if (n == 0) break;
    solve();
  }
}

###JAVA

import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;
class Edge {
  Edge(int a, int b) {
    to = a;
    cost = b;
  }
  int to;
  int cost;
}
class P {
  int dis; //最短距离
  int i; //顶点编号
  P(int a, int b) {
    dis = a;
    i = b;
  }
}
public class Main {
  public static void main(String[] args) {
    final int INF = Integer.MAX_VALUE / 2;
    Scanner cin = new Scanner(System.in);
    for (;;) {
      int n = cin.nextInt();
      int m = cin.nextInt();
      if (n == 0) break;
      PriorityQueue<P> pq = new PriorityQueue<P>((o1, o2) -> {
        if (o1.dis < o2.dis) return -1; else return 1;
      });
      ArrayList<Edge>[] g = new ArrayList[n];
      for (int i = 0; i < n; i++) {
        g[i] = new ArrayList<Edge>();
      }
      for (int i = 0; i < m; i++) {
        int a = cin.nextInt() - 1;
        int b = cin.nextInt() - 1;
        int c = cin.nextInt();
        g[a].add(new Edge(b, c));
        g[b].add(new Edge(a, c));
      }
      int[] d = new int[n];
      Arrays.fill(d, INF);
      d[0] = 0;
      pq.add(new P(0, 0));
      while (!pq.isEmpty()) {
        P p = pq.poll();
        int v = p.i;
        if (d[v] < p.dis) continue;
        for (Edge e : g[v]) {
          if (d[e.to] > d[v] + e.cost) {
            d[e.to] = d[v] + e.cost;
            pq.add(new P(d[e.to], e.to));
          }
        }
      }
      System.out.println(d[n - 1]);
    }
  }
}

##V1.0

import java.util.Arrays;
import java.util.Scanner;
public class Main {
  public static void main(String[] args) {
    Scanner cin = new Scanner(System.in);
    for (;;) {
      int n = cin.nextInt();
      int m = cin.nextInt();
      if (n == 0) break;
      int[][] cost = new int[n][n];
      for (int i = 0; i < n; i++) {
        Arrays.fill(cost[i], Integer.MAX_VALUE / 2);
        cost[i][i] = 0;
      }
      for (int i = 0; i < m; i++) {
        int a = cin.nextInt() - 1;
        int b = cin.nextInt() - 1;
        int c = cin.nextInt();
        cost[a][b] = c;
        cost[b][a] = c;
      }
      int[] d = new int[n];
      Arrays.fill(d, Integer.MAX_VALUE / 2);
      boolean[] used = new boolean[n];
      d[0] = 0;
      for (;;) {
        int v = -1;
        for (int u = 0; u < n; u++) {
          if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
        }
        if (v == -1) break;
        used[v] = true;
        for (int u = 0; u < n; u++) {
          d[u] = Math.min(d[u], d[v] + cost[v][u]);
        }
      }
      System.out.println(d[n - 1]);
    }
  }
}

##V1.1

import java.util.Arrays;
import java.util.Scanner;
public class Main {
  public static void main(String[] args) {
    final int INF = Integer.MAX_VALUE / 2;
    Scanner cin = new Scanner(System.in);
    for (;;) {
      int n = cin.nextInt();
      int m = cin.nextInt();
      if (n == 0) break;
      int[][] cost = new int[n][n];
      boolean[][] hasCost = new boolean[n][n];
      for (int i = 0; i < m; i++) {
        int a = cin.nextInt() - 1;
        int b = cin.nextInt() - 1;
        int c = cin.nextInt();
        cost[a][b] = c;
        cost[b][a] = c;
        hasCost[a][b] = true;
        hasCost[b][a] = true;
      }
      int[] d = new int[n];
      Arrays.fill(d, INF);
      boolean[] used = new boolean[n];
      d[0] = 0;
      for (;;) {
        int v = -1;
        for (int u = 0; u < n; u++) {
          if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
        }
        if (v == -1) break;
        used[v] = true;
        for (int u = 0; u < n; u++) {
          int w = d[v] + cost[v][u];
          if (!hasCost[v][u]) w = INF;
          d[u] = Math.min(d[u], w);
        }
      }
      System.out.println(d[n - 1]);
    }
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值