d.各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,

问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。

问题2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。
s.
首先找强连通分量,然后看强连通分量的入度为0点的总数,出度为0点的总数。

第一问为入度为0的强连通分量的个数。

第二问为入度为0的个数和出度为0的个数中大的。(将这个图的所有子树找出来,然后将一棵子树的叶子结点(出度为0)连到另外一棵子树的根结点上(入度为0),这样将所有的叶子结点和根节点全部消掉之后,就可以得到一整个强连通分量,看最少多少条边,这样就是看叶子结点和根节点哪个多,即出度为0和入度为0哪个多。证明?)

c.Tarjan

/*
Tarjan算法
复杂度O(N+M)
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std; const int MAXN=;//点数
const int MAXM=;//边数
struct Edge{
int to,next;
}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
int Index,top;
int scc;//强连通分量的个数
bool Instack[MAXN];
int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
//num数组不一定需要,结合实际情况 void addedge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void Tarjan(int u){
int v;
Low[u]=DFN[u]=++Index;
Stack[top++]=u;
Instack[u]=true;
for(int i=head[u];i!=-;i=edge[i].next){
v=edge[i].to;
if(!DFN[v]){
Tarjan(v);
if(Low[u]>Low[v])Low[u]=Low[v];
}
else if(Instack[v]&&Low[u]>DFN[v])
Low[u]=DFN[v];
}
if(Low[u]==DFN[u]){
scc++;
do{
v=Stack[--top];
Instack[v]=false;
Belong[v]=scc;
num[scc]++;
}
while(v!=u);
}
}
void solve(int N){
memset(DFN,,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
memset(num,,sizeof(num));
Index=scc=top=;
for(int i=;i<=N;i++)
if(!DFN[i])
Tarjan(i);
}
void init(){
tot=;
memset(head,-,sizeof(head));
} int main(){
int N;
int v; int indegree[MAXN],outdegree[MAXN];//强连通分量的入度,强连通分量的出度
int in0,out0;//入度为0的强连通分量个数,出度为0的... while(~scanf("%d",&N)){
init();
memset(indegree,,sizeof(indegree));
memset(outdegree,,sizeof(outdegree));
in0=out0=; for(int u=;u<=N;++u){
while(scanf("%d",&v)){
if(v==)break;
addedge(u,v);
}
} solve(N); if(scc==)printf("1\n0\n");//只有一个强连通 分量
else{
//枚举所有的边,统计强连通分量的入度、出度
for(int i=;i<=N;++i){
for(int j=head[i];j!=-;j=edge[j].next){
if(Belong[i]!=Belong[edge[j].to]){
++indegree[Belong[edge[j].to]];
++outdegree[Belong[i]];
}
}
}
//强连通分量的入度为0的个数,出度为0的个数
for(int i=;i<=scc;++i){
if(indegree[i]==)++in0;
if(outdegree[i]==)++out0;
} if(in0>out0)printf("%d\n%d\n",in0,in0);
else printf("%d\n%d\n",in0,out0);
}
}
return ;
}

最新文章

  1. 一个用shell写的统计目录下统计文件行数的代码
  2. ASP.NET Core 1.0 安装并发布到Centos 7.2 使用jexus 5.8.2
  3. 模拟赛1101d2
  4. 基于jQuery点击加载动画按钮特效
  5. 《TCP/IP 详解 卷一》读书笔记-----IP静态 路由
  6. TFS 2010 使用手册(四)备份与恢复
  7. 小编接地气——第六届中国云计算大会攻略Q&amp;amp;A
  8. paramiko SSH 模块简单应用。
  9. 获取前端post方式传过来的JSON格式的数据的代码
  10. bytes与str
  11. poj 1423 打表/斯特林公式
  12. Linux,Ubuntu,Mint 环境下 navicat 乱码问题
  13. CentOS 7安装Python3.5
  14. mormot支持TCP/IP
  15. MySQL占用IO过高解决方案【转】
  16. C++中的extern
  17. (笔记)AT91SAM9260的启动过程详细解说
  18. JDK源码之HashSet
  19. .NET:System.Security.Cryptography.CryptographicException 的解决办法
  20. Swift3 文件操作常用方法汇总

热门文章

  1. webStorm汉化
  2. RabbitMQ核心组件及应用场景
  3. [JSOI2016]反质数序列
  4. Scrum软件开发
  5. 让win7任务条上的文件夹打开是c,d,e,f而不是库
  6. 50 个 Bootstrap 插件
  7. Matlab中配置VLFeat
  8. [Adobe Analytics] Segments types
  9. SolidEdge 工程图中如何绘制中断视图
  10. 【整理】nand相关