zoukankan      html  css  js  c++  java
  • ccf认证 201709-4 通信网络 java实现

    试题编号:                                                               201709-4
    试题名称: 通信网络
    时间限制: 1.0s
    内存限制: 256.0MB
    问题描述:
    问题描述
      某国的军队由N个部门组成,为了提高安全性,部门之间建立了M条通路,每条通路只能单向传递信息,即一条从部门a到部门b的通路只能由ab传递信息。信息可以通过中转的方式进行传递,即如果a能将信息传递到bb又能将信息传递到c,则a能将信息传递到c。一条信息可能通过多次中转最终到达目的地。
      由于保密工作做得很好,并不是所有部门之间都互相知道彼此的存在。只有当两个部门之间可以直接或间接传递信息时,他们才彼此知道对方的存在。部门之间不会把自己知道哪些部门告诉其他部门。

      上图中给了一个4个部门的例子,图中的单向边表示通路。部门1可以将消息发送给所有部门,部门4可以接收所有部门的消息,所以部门1和部门4知道所有其他部门的存在。部门2和部门3之间没有任何方式可以发送消息,所以部门2和部门3互相不知道彼此的存在。
      现在请问,有多少个部门知道所有N个部门的存在。或者说,有多少个部门所知道的部门数量(包括自己)正好是N
    输入格式
      输入的第一行包含两个整数NM,分别表示部门的数量和单向通路的数量。所有部门从1到N标号。
      接下来M行,每行两个整数ab,表示部门a到部门b有一条单向通路。
    输出格式
      输出一行,包含一个整数,表示答案。
    样例输入
    4 4
    1 2
    1 3
    2 4
    3 4
    样例输出
    2
    样例说明
      部门1和部门4知道所有其他部门的存在。
    评测用例规模与约定
      对于30%的评测用例,1 ≤ N ≤ 10,1 ≤ M ≤ 20;
      对于60%的评测用例,1 ≤ N ≤ 100,1 ≤ M ≤ 1000;
      对于100%的评测用例,1 ≤ N ≤ 1000,1 ≤ M ≤ 10000。

    这是一道深度优先搜索的图论。。

    把它理解成:

    输入一个图,我们判断一下 有几个节点能到其他所有节点和 有几个节点能被其他所有节点访问到。

    题目中说是单项图,但是问题是 能访问所有节点和能被所有节点访问都算数,所以和双向图也没有区别,

    把它理解成 图中哪些节点与其他所有节点有通路就可以了。

     

    需要用到深度优先遍历的思想,具体这样实现:

    有n个点 m条路

    1 建立一个邻接表:n长度的数组line,数组里每个位置存一张链表, line[i] 的链表里存着 所有能从i点出发到达的节点的编号。

    2 建立一个n*n二维表graph  代表整个图,,我们要对 邻接表line进行深度优先遍历,

      在line中 root从1到n  依次拿i当做根节点编号root, 拿到line[root] 链表,

        在链表里所有的节点i都能从root出发到达,我们就在graph[root][i]和graph[i][root]标记为1 表明他们连同

        同时i节点能到达的节点,root也能间接到达,所以 我们再对line[i] 列表里所有的节点标号进行在graph上标记连通。

        为了防止图中出现循环通路的情况,我用用一个visited表进行标记 同一个root出发进行深度遍历的时候,访问到某个节点i 就把visited[i] 设为1 表示访问过了,跳过访问

     

    这里我们要深度优先,所以 要在循环里面递归。

    最后我们再graph上进行统计 某一行所有数据都是1  那么说明他和所有点都能连通。

     

    java代码:

           

     1 import java.util.ArrayList;
     2 import java.util.List;
     3 import java.util.Scanner;
     4 
     5 public class Main{
     6     public Scanner fin;    // 标准输入
     7     public int n,m;    // 点的个数和路径的个数
     8     public int visited[]; // 标记每次深度搜索是否遍历过目标节点 方式无限递归
     9     public List<Integer>[] line;    // 第i个列表存i能到达的所有节点编号
    10     public int[][] graph;    // 二维表i j  标记i和j之间有通路
    11     public int root;     // 记录每次遍历的根节点
    12     public int count=0;    // 最终结果哦
    13     
    14     public static void main(String[] args) {
    15         new Main().run();
    16     }
    17     public void run() {
    18         init();
    19         // 输入每条路 
    20         for(int i=1;i<=m;i++) {
    21             int a = fin.nextInt();
    22             int b = fin.nextInt();
    23             line[a].add(b);    // a节点能到达b节点
    24         }
    25         // 对每一个节点 进行深度优先遍历,更新二维表graph  将i 和j 两个节点之间有路的 二维表相应位置设为1
    26         for(int i=1;i<=n;i++) {
    27             // 对每次从根节点遍历子节点进行初始化visited数组
    28             visited = new int[n+1];
    29             root = i;
    30             dfs(i);
    31         }
    32         // 统计能够知道所有其他节点的节点个数
    33         for(int i=1;i<=n;i++) {
    34             for(int j=1;j<=n;j++) {
    35                 if(graph[i][j]==0) {
    36                     break;
    37                 }
    38                 if(j==n) {
    39                     count ++;
    40                 }
    41             }
    42         }
    43         System.out.println(count);
    44         
    45         
    46     }
    47     public void dfs(int cur) {
    48         // 根节点和当前子节点能够通路
    49         graph[root][cur] = 1;
    50         graph[cur][root] = 1;
    51         visited[cur] = 1;
    52         // 对cur节点能到达的节点列表遍历
    53         for(int i=0;i<line[cur].size();i++) {
    54             if(visited[line[cur].get(i)]==0) {        // 如果当前子节点还没有被访问过
    55                 dfs(line[cur].get(i));
    56             }
    57         }
    58     }
    59     
    60     public void init() {
    61         fin = new Scanner(System.in);
    62         n = fin.nextInt();
    63         m = fin.nextInt();
    64         visited = new int[n+1];
    65         line = new List[n+1];
    66         for(int i=1;i<=n;i++) {
    67             line[i] = new ArrayList<>();
    68         }
    69         graph = new int[n+1][n+1];
    70         
    71     }
    72     
    73 }

     

  • 相关阅读:
    初窥RabbitMQ消息中间及SpringBoot整合
    博客园页面嵌入左下角小女孩
    不依赖Spring使用AspectJ达到AOP面向切面编程
    彻底搞懂计算机网络通信设备与协议
    博客园如何嵌入网易云音乐播放器
    并发编程之详解InheritableThreadLocal类原理
    2小时学会Spring Boot(IDE:eclipse)
    $.Ajax、$.Get、$.Post代码实例参数解析
    设计模式之空对象模式
    设计模式之黑板模式
  • 原文地址:https://www.cnblogs.com/Lin-Yi/p/8568774.html
Copyright © 2011-2022 走看看