CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址

CCF CSP 201709-4 通信网络

问题描述

  某国的军队由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个节点存在的节点。

统计一个节点父节点的个数可以通过N个深度优先搜索得到。从每一个节点开始进行深度优先搜索,每到达一个节点,该节点的计数加一。复杂度为O(V(V+E))

将图的所有边反向,便可以统计一个节点子节点的个数。

如果图存在环,在同一个强连通分量内的节点互相为父子节点,上面的方法便失效了。解决方案是首先进行强连通分量的分解。代码中使用了Kosaraju算法进行强连通分量的分解。复杂度为O(V+E)

分解后得到每一个顶点的强连通分量标号。

然后计算每一个节点父强连通分量的个数与子强连通分量的个数。这一步从每一个强连通分量中选择一个顶点开始进行深度优先搜索,如果当前所在强连通分量的标签与起始节点强连通分量标签不同,则该节点计数加一。

如果一个顶点父强连通分量的个数加上子强连通分量的个数加一等于总强连通分量个数,那么这个节点知道所有节点的存在。

代码

C++

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #define MAX_V 1001
  5. using namespace std;
  6.  
  7. int N, M;
  8. vector<int> G[MAX_V], rG[MAX_V];
  9. vector<int> postorder;
  10. bool used[MAX_V];
  11. int label[MAX_V]; // 每一个节点所属强连通分量的标号
  12. int sccv[MAX_V]; // 每一个强连通分量的一个顶点
  13. int nparent[MAX_V], nchild[MAX_V]; // 每一个节点父/子强连通分量个数
  14.  
  15. // 生成图的后序遍历
  16. void dfs(int u) {
  17. for(int i=; i<G[u].size(); i++) {
  18. int v = G[u][i];
  19. if(!used[v]) {
  20. used[v] = true;
  21. dfs(v);
  22. }
  23. }
  24. postorder.push_back(u);
  25. }
  26.  
  27. int rdfs(int u, int l) {
  28. label[u] = l;
  29. for(int i=; i<rG[u].size(); i++) {
  30. int v = rG[u][i];
  31. if(!used[v]) {
  32. used[v] = true;
  33. rdfs(v, l);
  34. }
  35. }
  36. }
  37.  
  38. // Kosaraju算法 分解强连通分量
  39. int SCC() {
  40. fill(used, used+MAX_V, );
  41. for(int n=; n<=N; n++) {
  42. if(!used[n]) {
  43. used[n] = true;
  44. dfs(n);
  45. }
  46. }
  47. fill(used, used+MAX_V, );
  48. int l = ;
  49. for(int n=N-; n>=; n--) {
  50. int v = postorder[n];
  51. if(!used[v]) {
  52. l++;
  53. used[v] = true;
  54. rdfs(v, l);
  55. sccv[l] = v;
  56. }
  57. }
  58. return l;
  59. }
  60.  
  61. // 统计u所在强连通分量能够到达的其它强连通分量
  62. void dfs2(int u, int l, int (&nparent)[MAX_V], vector<int> (&G)[MAX_V]) {
  63. if(label[u] != l) nparent[u]++;
  64. for(int i=; i<G[u].size(); i++) {
  65. int v = G[u][i];
  66. if(!used[v]) {
  67. used[v] = true;
  68. dfs2(v, l, nparent, G);
  69. }
  70. }
  71. }
  72.  
  73. int main() {
  74. cin >> N >> M;
  75. for(int m=; m<M; m++) {
  76. int a, b;
  77. cin >> a >> b;
  78. G[a].push_back(b);
  79. rG[b].push_back(a);
  80. }
  81.  
  82. int numc = SCC();
  83.  
  84. // 统计每一个顶点父强连通分量个数
  85. for(int i=; i<=numc; i++) {
  86. fill(used, used+MAX_V, );
  87. int v = sccv[i];
  88. used[v] = true;
  89. dfs2(v, label[v], nparent, G);
  90. }
  91.  
  92. // 统计每一个顶点子强连通分量个数
  93. for(int i=; i<=numc; i++) {
  94. fill(used, used+MAX_V, );
  95. int v = sccv[i];
  96. used[v] = true;
  97. dfs2(v, label[v], nchild, rG);
  98. }
  99.  
  100. int cnt = ;
  101. for(int n=; n<=N; n++) {
  102. // 如果父强连通分量个数加子强连通分量个数加一等于总强连通分量个数
  103. if(nparent[n]+nchild[n]+==numc) cnt++;
  104. }
  105. cout << cnt;
  106. }

CCF CSP 201709-4 通信网络的更多相关文章

  1. CCF CSP 201403-4 无线网络

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201403-4 无线网络 问题描述 目前在一个很大的平面房间里有 n 个无线路由器,每个无线路 ...

  2. CCF CSP 201503-4 网络延时

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201503-4 网络延时 问题描述 给定一个公司的网络,由n台交换机和m台终端电脑组成,交换机 ...

  3. ccf认证 201709-4 通信网络 java实现

    试题编号:                                                               201709-4 试题名称: 通信网络 时间限制: 1.0s 内 ...

  4. csp 通信网络

    http://blog.csdn.net/zyy_1998/article/details/78334496 试题编号: 201709-4 试题名称: 通信网络 时间限制: 1.0s 内存限制: 25 ...

  5. 通信网络 ccf

    试题编号: 201709-4 试题名称: 通信网络 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 某国的军队由N个部门组成,为了提高安全性,部门之间建立了M条通路,每条通路只 ...

  6. CCF(通信网络):简单DFS+floyd算法

    通信网络 201709-4 一看到题目分析了题意之后,我就想到用floyd算法来求解每一对顶点的最短路.如果一个点和任意一个点都有最短路(不为INF),那么这就是符合的一个答案.可是因为题目超时,只能 ...

  7. 小dai浅谈通信网络(一)——引子

    说起通信网络,首先来看一个场景: 场景模式: 小明和小刚在闹市碰面. 小明对小刚大声喊道:"小刚,你好啊!" 小刚摇手答到:"你好,小明!" 就这么几句简单的话 ...

  8. 浅谈通信网络(三)——TCP/IP协议

    简介 Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议.In ...

  9. CCF CSP 认证

    参加第八次CCF CSP认证记录 代码还不知道对不对,过两天出成绩. 成绩出来了,310分. 100+100+100+10+0: 考试13:27开始,17:30结束,提交第4题后不再答题,只是检查前四 ...

随机推荐

  1. 关于ARGB_8888、ALPHA_8、ARGB_4444、RGB_565的理解

    关于ARGB_8888.ALPHA_8.ARGB_4444.RGB_565的理解 A:透明度 R:红色 G:绿 B:蓝 Bitmap.Config ARGB_4444:每个像素占四位,即A=4,R=4 ...

  2. SCOI2012喵星球上的点名

    http://codevs.cn/problem/2403/ 2012年省队选拔赛四川  时间限制: 2 s  空间限制: 128000 KB   题目描述 Description a180285幸运 ...

  3. stl第二级空间配置器详解(1)

    SGI STL考虑到小型内存区块的碎片问题,设计了双层级配置器,第一级配置直接使用malloc()和free():第二级配置器则视情况采用不同的策略,当配置区大于128bytes时,直接调用第一级配置 ...

  4. 网页制作中最有用的免费Ajax和JavaScript代码库

    网上看到的一篇小文,挺有用的,收藏在这. 本文中,我整理了12个免费的Ajax和JavaScript代码库,可以帮助Web开发人员将应用程序提升到一个新水平. Ajax Instant Messeng ...

  5. linux查看及设置别名,权限,生成ssh秘钥

    1.alias :查看系统中所有的命令别名 2.设定别名 alias 别名='原命令' 3.删除别名 unalias 别名 4.使别名永久生效    vi  ~/.bashrc  写入这个文件中即可永 ...

  6. Android笔记之开机自启

    有时候需要应用具有开机自启的能力,或者更常见的场景是开机时悄悄在后台启动一个Service. 关键点: 1. Android系统在开机的时候会发送一条广播消息,只需要接收这条广播消息即可,不过需要注意 ...

  7. 34、Collections工具类简介

    Collections工具类简介 就像数组中的Arrays工具类一样,在集合里面也有跟Arrays类似的工具类Collections package com.sutaoyu.Collections; ...

  8. AutoCAD DevTV-AUTOCAD二次开发资源合集

    Webcast Language Date AutoCAD .Net - Session 2 English 13-Sep-12 AutoCAD .Net - Session 1 English 6- ...

  9. SpringCloud之Eureka(注册中心集群篇)

    一:集群环境搭建 第一步:我们新建两个注册中心工程一个叫eureka_register_service_master,另一个叫eureka_register_service_backup eureka ...

  10. vtk 基础概念

    #include <vtk-5.10/vtkSmartPointer.h>#include <vtk-5.10/vtkRenderWindow.h>#include <v ...