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++

#include <iostream>
#include <vector>
#include <algorithm>
#define MAX_V 1001
using namespace std; int N, M;
vector<int> G[MAX_V], rG[MAX_V];
vector<int> postorder;
bool used[MAX_V];
int label[MAX_V]; // 每一个节点所属强连通分量的标号
int sccv[MAX_V]; // 每一个强连通分量的一个顶点
int nparent[MAX_V], nchild[MAX_V]; // 每一个节点父/子强连通分量个数 // 生成图的后序遍历
void dfs(int u) {
for(int i=; i<G[u].size(); i++) {
int v = G[u][i];
if(!used[v]) {
used[v] = true;
dfs(v);
}
}
postorder.push_back(u);
} int rdfs(int u, int l) {
label[u] = l;
for(int i=; i<rG[u].size(); i++) {
int v = rG[u][i];
if(!used[v]) {
used[v] = true;
rdfs(v, l);
}
}
} // Kosaraju算法 分解强连通分量
int SCC() {
fill(used, used+MAX_V, );
for(int n=; n<=N; n++) {
if(!used[n]) {
used[n] = true;
dfs(n);
}
}
fill(used, used+MAX_V, );
int l = ;
for(int n=N-; n>=; n--) {
int v = postorder[n];
if(!used[v]) {
l++;
used[v] = true;
rdfs(v, l);
sccv[l] = v;
}
}
return l;
} // 统计u所在强连通分量能够到达的其它强连通分量
void dfs2(int u, int l, int (&nparent)[MAX_V], vector<int> (&G)[MAX_V]) {
if(label[u] != l) nparent[u]++;
for(int i=; i<G[u].size(); i++) {
int v = G[u][i];
if(!used[v]) {
used[v] = true;
dfs2(v, l, nparent, G);
}
}
} int main() {
cin >> N >> M;
for(int m=; m<M; m++) {
int a, b;
cin >> a >> b;
G[a].push_back(b);
rG[b].push_back(a);
} int numc = SCC(); // 统计每一个顶点父强连通分量个数
for(int i=; i<=numc; i++) {
fill(used, used+MAX_V, );
int v = sccv[i];
used[v] = true;
dfs2(v, label[v], nparent, G);
} // 统计每一个顶点子强连通分量个数
for(int i=; i<=numc; i++) {
fill(used, used+MAX_V, );
int v = sccv[i];
used[v] = true;
dfs2(v, label[v], nchild, rG);
} int cnt = ;
for(int n=; n<=N; n++) {
// 如果父强连通分量个数加子强连通分量个数加一等于总强连通分量个数
if(nparent[n]+nchild[n]+==numc) cnt++;
}
cout << cnt;
}

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. day7 方法及基础知识运用

    做了一个小型的成绩管理系统.主要代码如下: /* * 功能:简易学生成绩管理系统 */package day7; import java.util.Scanner; public class Home ...

  2. UITableViewCell的separatorInset属性

    separatorInset这个属性是IOS7后才有的属性,所以需要判断一下,才能修改 if (IOS7_OR_LATER) { cell.separatorInset = UIEdgeInsetsZ ...

  3. 11 Facts about Data Science that you must know

    11 Facts about Data Science that you must know Statistics, Machine Learning, Data Science, or Analyt ...

  4. 关于mysql 5.7版本“报[Err] 1093 - You can't specify target table 'XXX' for update in FROM clause”错误的bug

    不同于oracle和sqlserver,mysql并不支持在更新某个表的数据时又查询了它,而查询的数据又做了更新的条件,因此我们需要使用如下的语句绕过: , notice_code ) a) ; 本地 ...

  5. 织梦自定义表单通过ajax提交的实现方法

    自定义表单通过ajax判断,提交不用跳转页面,提高用户体验.具体方法如下: html表单代码部分,就提交按钮改成botton,,添加onclick事件 表单代码: <form action=&q ...

  6. 动态引用外部的Javascript脚本文件[转]

    你可以参考下面方法,进行动态为网页引用外部的Javascript脚本文件.代码写在Page_Init方法内. VB.NET: 下图是运行时,查看HTML的源代码: C#:

  7. HDU 1027 Ignatius and the Princess II 排列生成

    解题报告:1-n这n个数,有n!中不同的排列,将这n!个数列按照字典序排序,输出第m个数列. 第一次TLE了,没注意到题目上的n和m的范围,n的范围是小于1000的,然后m的范围是小于10000的,很 ...

  8. 初时Python博大精深

    Python是解释型语言 编译型vs解释型 编译型优点:编译器一般会有预编译的过程对代码进行优化.因为编译只做一次,运行时不需要编译,所以编译型语言的程序执行效率高.可以脱离语言环境独立运行.缺点:编 ...

  9. 【译】第十四篇 Integration Services:项目转换

    本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...

  10. UNIX环境高级编程 第11章 线程

    使用C++调用pthread_cleanup_push( )时,下面的代码是无法编译通过的: pthread_cleanup_push(cleanup, "thread 1 first ha ...