电话网络问题

x33g5p2x  于2022-07-04 转载在 其他  
字(1.6k)|赞(0)|评价(0)|浏览(339)

一 原问题链接

Network - POJ 1144 - Virtual Judge

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

二 输入与输出

1 输入

输入包含多个测试用例。每个测试用例都描述一个网络。每个测试用例的第 1 行都是 N。接下来最多  N 行中每一行都包含一个地点的编号,后面是该地方可以直达的地点编号。每个测试用例都以一条仅包含0的行结束。N=0时输入结束,不处理。

2 输出

对每个测试用例,都单行输出关键位置的数量。

三 输入样例

5

5 1 2 3 4

0

6

2 1 3

5 4 6 2

0

0

四 输出样例

1

2

五 问题分析

1 输入样例1,构建的图如下。在该图中有1个关键点5。

2 输入样例2,构建的图如下。在该图中有两个关键点,分别是2和5。

本问题就是求割点数,利用 Tarjan 算法求解即可。

六 代码

  1. package graph.poj1144;
  2. import java.util.Scanner;
  3. public class POJ1144 {
  4. static final int maxn = 1000 + 5;
  5. static int n;
  6. static int m;
  7. static int head[];
  8. static int cnt;
  9. static int root;
  10. static int low[];
  11. static int dfn[];
  12. static int cut[];
  13. static int num;
  14. static Edge e[] = new Edge[maxn << 1];
  15. static {
  16. for (int i = 0; i < e.length; i++) {
  17. e[i] = new Edge();
  18. }
  19. }
  20. static void add(int u, int v) { // 添加一条边u--v
  21. e[++cnt].next = head[u];
  22. e[cnt].to = v;
  23. head[u] = cnt;
  24. }
  25. static void tarjan(int u) { //求割点
  26. dfn[u] = low[u] = ++num;
  27. int flag = 0;
  28. for (int i = head[u]; i != 0; i = e[i].next) {
  29. int v = e[i].to;
  30. if (dfn[v] == 0) {
  31. tarjan(v);
  32. low[u] = Math.min(low[u], low[v]);
  33. if (low[v] >= dfn[u]) {
  34. flag++;
  35. if (u != root || flag > 1) {
  36. cut[u] = 1;
  37. }
  38. }
  39. } else
  40. low[u] = Math.min(low[u], dfn[v]);
  41. }
  42. }
  43. static void init() {
  44. head = new int[maxn];
  45. low = new int[maxn];
  46. dfn = new int[maxn];
  47. cut = new int[maxn];
  48. cnt = num = 0;
  49. }
  50. public static void main(String[] args) {
  51. Scanner scanner = new Scanner(System.in);
  52. while (true) {
  53. n = scanner.nextInt();
  54. if (n == 0)
  55. break;
  56. init();
  57. int u, v;
  58. while (true) {
  59. Scanner scanner1 = new Scanner(System.in);
  60. String nums = scanner1.nextLine();
  61. String[] s = nums.split(" ");
  62. u = Integer.parseInt(s[0]);
  63. if (u == 0) {
  64. break;
  65. }
  66. for (int i = 1; i < s.length; i++) {
  67. v = Integer.parseInt(s[i]);
  68. add(u, v);
  69. add(v, u);
  70. }
  71. }
  72. for (int i = 1; i <= n; i++) {
  73. if (dfn[i] == 0) {
  74. root = i;
  75. tarjan(i);
  76. }
  77. }
  78. int ans = 0;
  79. for (int i = 1; i <= n; i++)
  80. if (cut[i] == 1)
  81. ans++;
  82. System.out.println(ans);
  83. }
  84. }
  85. }
  86. class Edge {
  87. int to;
  88. int next;
  89. }

七 测试结果

绿色为输入,白色为输出

相关文章