互联网问题

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

一 原问题链接

Networking - POJ 1287 - Virtual Judge

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

二 输入和输出

1 输入

输入由多个数据集组成,每个数据集都描述一个网络。数据集的第1行包括两个整数:第1个整数表示点数P,节点标号为1~P;第2个整数表点之间的路线数R。以下 R 行为点之间的路线,每条路线包括3个整数:前两个整数为点标号,第3个整数为路线长度L。数据集之间以空格分隔,输入仅有一个数字P(p=0),表示输入结束。

2 输出

对于每个数据集,都单行输出所设计网络的电缆的最小总长度。

三 输入和输出样例

1 输入样例

1 0

2 3

1 2 37

2 1 17

1 2 68

3 7

1 2 19

2 3 11

3 1 7

1 3 5

2 3 89

3 1 91

1 2 32

5 7

1 2 5

2 3 7

2 4 8

4 5 11

3 5 10

1 5 6

4 2 12

0

2 输出样例

0

17

16

26

四 算法设计

本问题是简单的最小生成树问题,可以采用 Prim 或 Kruskal 算法求解。在此使用并查集优化的 Kruskal 算法。

1 初始化。将所有的边都按权值从小到大排序,将每个节点的集合号都初始化为自身编号。

2 按排序后的顺序选择权值最小的边(u,v)。

3 如果节点 u 和 v 属于两个不同的连通分支,则采用并查集对两个连通分支进行合并,累加边(u,v)的权值。

4 如果选择的边数小于 n-1,则转向步骤2,否则算法结束,返回和值。

五 代码

  1. package graph.poj1287;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. import java.util.Scanner;
  6. public class POJ1287 {
  7. static int fa[] = new int[55];
  8. static int n;
  9. static int m;
  10. static int cnt;
  11. static node edge[] = new node[3000];
  12. static List<node> nodeList = new ArrayList();
  13. static void add(int a, int b, int c) {
  14. edge[cnt].u = a;
  15. edge[cnt].v = b;
  16. edge[cnt].cost = c;
  17. nodeList.add(edge[cnt]);
  18. cnt++;
  19. }
  20. static int find(int x) { // 并查集找祖宗
  21. if (x != fa[x]) {
  22. fa[x] = find(fa[x]);
  23. }
  24. return fa[x];
  25. }
  26. // 合并
  27. static boolean merge(int a, int b) {//集合合并
  28. int x = find(a);
  29. int y = find(b);
  30. if (x == y) return false;
  31. fa[y] = x;
  32. return true;
  33. }
  34. static int kruskal() {
  35. int sum = 0;
  36. Collections.sort(nodeList);
  37. for (int i = 0; i < m; i++) {
  38. if (merge(nodeList.get(i).u, nodeList.get(i).v)) {
  39. sum += nodeList.get(i).cost;
  40. if (--n == 1)
  41. return sum;
  42. }
  43. }
  44. return 0;
  45. }
  46. public static void main(String[] args) {
  47. Scanner scanner = new Scanner(System.in);
  48. int x, y, z;
  49. while (true) {
  50. n = scanner.nextInt();
  51. if (n == 0) return;
  52. nodeList.clear();
  53. for (int i = 0; i < edge.length; i++) {
  54. edge[i] = new node();
  55. }
  56. cnt = 0;
  57. m = scanner.nextInt();
  58. for (int i = 1; i <= n; i++)
  59. fa[i] = i;
  60. for (int i = 0; i < m; i++) {
  61. x = scanner.nextInt();
  62. y = scanner.nextInt();
  63. z = scanner.nextInt();
  64. add(x, y, z);
  65. }
  66. System.out.println(kruskal());
  67. }
  68. }
  69. }
  70. class node implements Comparable {
  71. int u;
  72. int cost;
  73. int v;
  74. @Override
  75. public int compareTo(Object o) {
  76. if (this.cost > ((node) o).cost) {
  77. return 1;
  78. } else if (this.cost == ((node) o).cost) {
  79. return 0;
  80. } else {
  81. return -1;
  82. }
  83. }
  84. }

六 测试

绿色为输入,白色为输出

相关文章