道路建设问题

x33g5p2x  于2022-07-13 转载在 其他  
字(1.3k)|赞(0)|评价(0)|浏览(366)

一 原问题链接

Constructing Roads - POJ 2421 - Virtual Judge

https://vjudge.net/problem/POJ-2421

二 输入和输出

1 输入

第 1 行是整数 N,表示村庄的数量;然后是 N 行,其中第 i 行包含 N 个整数,第 j 个整数表示村庄 i 和村庄 j 之间的距离;接着是整数 Q,表示已建成的道路的数量;然后是 Q 行,每行都包含两个整数 a 和 b,表示村庄 a 和村庄 b 之间的道路已经建成。

2 输出

单行输出需要构建的所有道路的最小长度。

三 输入和输出样例

1 输入样例

3

0 990 692

990 0 179

692 179 0

1

1 2

2 输出样例

179

四 分析

本问题属于最小生成树问题,不同的是本问题有一些道路已经建成,将这些道路的边权设置为0,然后采用 Prim 或 Kruskal 算法求解最小生成树即可。

五 代码

  1. package graph.poj2421;
  2. import java.util.Scanner;
  3. public class POJ2421 {
  4. static final int maxn = 105;
  5. static final int inf = 0x3f3f3f3f;
  6. static int m[][] = new int[maxn][maxn];
  7. static int low[] = new int[maxn];
  8. static boolean vis[] = new boolean[maxn];
  9. static int n;
  10. static int prim(int s) {
  11. for (int i = 0; i < vis.length; i++) {
  12. vis[i] = false;
  13. }
  14. for (int i = 1; i <= n; i++)
  15. low[i] = m[s][i];
  16. vis[s] = true;
  17. int sum = 0;
  18. int t = 1;
  19. for (int i = 1; i < n; i++) { // 执行 n-1 次
  20. int min = inf;
  21. for (int j = 1; j <= n; j++) { // 找最小
  22. if (!vis[j] && low[j] < min) {
  23. min = low[j];
  24. t = j;
  25. }
  26. }
  27. sum += min;
  28. vis[t] = true;
  29. for (int j = 1; j <= n; j++) {//更新
  30. if (!vis[j] && low[j] > m[t][j])
  31. low[j] = m[t][j];
  32. }
  33. }
  34. return sum;
  35. }
  36. public static void main(String[] args) {
  37. Scanner scanner = new Scanner(System.in);
  38. int q, a, b;
  39. while (true) {
  40. n = scanner.nextInt();
  41. if (n == 0) {
  42. return;
  43. }
  44. for (int i = 1; i <= n; i++)
  45. for (int j = 1; j <= n; j++)
  46. m[i][j] = scanner.nextInt();
  47. q = scanner.nextInt();
  48. while (q-- > 0) {
  49. a = scanner.nextInt();
  50. b = scanner.nextInt();
  51. m[a][b] = m[b][a] = 0;
  52. }
  53. System.out.println(prim(1));
  54. }
  55. }
  56. }

六 测试

绿色为输入,白色为输出。

相关文章