(转载) poj1236 - Network of Schools
看到一篇挺好的代码,适合初学者,转载自 博主 wangjian8006
原地址:http://blog.csdn.net/wangjian8006/article/details/7888558
题目大意:有N个学校,从每个学校都能从一个单向网络到另外一个学校,两个问题
1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。
2:至少需要添加几条边,使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。
解题思路:
首先找连通分量,然后看连通分量的入度为0点的总数,出度为0点的总数,那么问要向多少学校发放软件,就是入度为零的个数,这样才能保证所有点能够找到
然后第二问添加多少条边可以得到使整个图达到一个强连通分量,答案是入度为0的个数和出度为0的个数中最大的那个
为什么会这样呢,经过我同学的讨论,将这个图的所有子树找出来,然后将一棵子树的叶子结点(出度为0)连到另外一棵子树的根结点上(入度为0),这样将所有的叶子结点和根节点全部消掉之后,就可以得到一整个强连通分量,看最少多少条边,这样就是看叶子结点和根节点哪个多,即出度为0和入度为0哪个多。我只能说这种策略是正确的,适用于一般图,但其实我觉得也不能够很有力的证明这个结论成立
/*
kosaraju
Memory 224K
Time 0MS
*/
#include <iostream>
using namespace std;
#define MAXV 110
#define max(a,b) (a>b?a:b) int map[MAXV][MAXV],order[MAXV],belong[MAXV],indegree[MAXV],outdegree[MAXV];
int n,num,count;
bool vis[MAXV]; void dfs(int x){
int i;
vis[x]=;
for(i=;i<=n;i++)
if(map[x][i] && !vis[i])
dfs(i);
order[++num]=x;
} void dfst(int x){
int i;
belong[x]=count; //记录结点属于哪个连通分量
vis[x]=;
for(i=;i<=n;i++)
if(!vis[i] && map[i][x])
dfst(i);
} void kosaraju(){
int i;
memset(vis,,sizeof(vis));
num=count=;
for(i=;i<=n;i++) //第一次搜索将时间戳从小到大排序
if(!vis[i]) dfs(i);
memset(vis,,sizeof(vis)); for(i=n;i>=;i--) //第二次搜索从时间戳大的开始走找连通分量
if(!vis[order[i]]){
count++; //连通分量个数
dfst(order[i]);
}
} void output(){
int i,j,inzero=,outzero=;
for(i=;i<=n;i++){
indegree[i]=outdegree[i]=;
}
for(i=;i<=n;i++) //找连通分量入度与出度
for(j=;j<=n;j++)
if(map[i][j] && belong[i]!=belong[j]){
indegree[belong[j]]++;
outdegree[belong[i]]++;
}
for(i=;i<=count;i++){ //找入度与出度为0的点
if(!indegree[i]) inzero++;
if(!outdegree[i]) outzero++;
} if(count==) //只有1个结点要特判
printf("1\n0\n");
else
printf("%d\n%d\n",inzero,max(inzero,outzero));
} int main(){
int i,a;
while(~scanf("%d",&n)){
for(i=;i<=n;i++){
while(scanf("%d",&a) && a) map[i][a]=;
}
kosaraju();
output();
}
return ;
}
另一个用tarjan算法的实现
/*
tarjan
Memory 224K
Time 0MS
*/
#include <iostream>
using namespace std;
#define MAXV 110
#define min(a,b) (a>b?b:a)
#define max(a,b) (a>b?a:b) int n,map[MAXV][MAXV],outdegree[MAXV],indegree[MAXV];
int dfn[MAXV]; //第一次访问的步数
int low[MAXV]; //子树中最早的步数
int stap[MAXV],stop; //模拟栈
bool instack[MAXV]; //是否在栈中
int count; //记录连通分量的个数
int cnt; //记录搜索步数
int belong[MAXV]; //属于哪个连通分量 void init(){
count=stop=cnt=;
memset(instack,false,sizeof(instack));
memset(map,,sizeof(map));
memset(dfn,,sizeof(dfn));
} void tarjan(int x){
int i;
dfn[x]=low[x]=++cnt;
stap[stop++]=x;
instack[x]=true;
for(i=;i<=n;i++){
if(!map[x][i]) continue;
if(!dfn[i]){
tarjan(i);
low[x]=min(low[i],low[x]);
}else if(instack[i])
low[x]=min(dfn[i],low[x]);
//与x相连,但是i已经被访问过,且还在栈中
//用子树节点更新节点第一次出现的时间
} if(low[x]==dfn[x]){
count++;
while(){
int tmp=stap[--stop];
belong[tmp]=count;
instack[tmp]=false;
if(tmp==x) break;
}
}
} void output(){
int i,j,inzero=,outzero=;
for(i=;i<=n;i++){
indegree[i]=outdegree[i]=;
}
for(i=;i<=n;i++) //找连通分量入度与出度
for(j=;j<=n;j++)
if(map[i][j] && belong[i]!=belong[j]){
indegree[belong[j]]++;
outdegree[belong[i]]++;
}
for(i=;i<=count;i++){ //找入度与出度为0的点
if(!indegree[i]) inzero++;
if(!outdegree[i]) outzero++;
} if(count==) //只有1个结点要特判
printf("1\n0\n");
else
printf("%d\n%d\n",inzero,max(inzero,outzero));
} int main(){
int i,a;
while(~scanf("%d",&n)){
init();
for(i=;i<=n;i++){
while(scanf("%d",&a) && a) map[i][a]=;
}
for(i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
output();
}
return ;
}
(转载) poj1236 - Network of Schools的更多相关文章
- P2746 [USACO5.3]校园网Network of Schools// POJ1236: Network of Schools
P2746 [USACO5.3]校园网Network of Schools// POJ1236: Network of Schools 题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学 ...
- poj-1236.network of schools(强连通分量 + 图的入度出度)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 27121 Accepted: 10 ...
- POJ1236 - Network of Schools tarjan
Network of Schools Time Limit: 1000MS Memory Limi ...
- POJ1236 Network of Schools (强连通)(缩点)
Network of Schools Time Limit: 1000MS ...
- POJ-1236 Network of Schools,人生第一道Tarjan....
Network of Schools 题意:若干个学校组成一个计算机网络系统,一个学校作为出发端连接着若干个学校,信息可以传送到这些学校.被链接的学校不需要再次与出发端相连,现在问你:A:最少选几个学 ...
- POJ1236 Network of Schools —— 强连通分量 + 缩点 + 入出度
题目链接:http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K Tot ...
- POJ1236 Network of Schools (强连通分量,注意边界)
A number of schools are connected to a computer network. Agreements have been developed among those ...
- poj1236 Network of Schools【强连通分量(tarjan)缩点】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html ---by 墨染之樱花 [题目链接]http://poj.org/pr ...
- POJ1236 network of schools
100个学校,有单向网络连接,从而分享软件. 问题一:几个学校得到软件就可使所有学校都得到? 问题二:再加几条单向网络可以使得"任意学校得到软件,就可使得所有学校都有软件"? -- ...
随机推荐
- 花园【SCOI2017期望DP入门题】
题目描述: 小 A 的花园的长和宽分别是 L,H .小 A 喜欢在花园里做游戏.每次做游戏的时候,他都先把花园均匀分割成 L×H 个小方块,每个方块的长和宽都是 1 .然后,小 A 会从花园的西北角的 ...
- VS2010-MFC(对话框:模态对话框及其弹出过程)
转自:http://www.jizhuomi.com/software/160.html 一.模态对话框和非模态对话框 Windows对话框分为两类:模态对话框和非模态对话框. 模态对话框是这样的对话 ...
- 2018CCPC吉林赛区 | 部分题解 (HDU6555 HDU6556 HDU6559 HDU6561)
// 杭电上的重现赛:http://acm.hdu.edu.cn/contests/contest_show.php?cid=867 // 杭电6555~6566可交题 A - The Fool 题目 ...
- linux socket error code
errno.00 is: Successerrno.01 is: Operation not permittederrno.02 is: No such file or directoryerrno. ...
- 分布式配置中心(Spring Cloud Config)
真有意思的一个问题,我先把我遇到的写一次 ,今天学习Spring Cloud Config 新建了三个module ,eureka-server,config-server,config-clien ...
- 2018-12-6-Roslyn-如何基于-Microsoft.NET.Sdk-制作源代码包
title author date CreateTime categories Roslyn 如何基于 Microsoft.NET.Sdk 制作源代码包 lindexi 2018-12-06 16:2 ...
- 【深度学习】CNN 中 1x1 卷积核的作用
[深度学习]CNN 中 1x1 卷积核的作用 最近研究 GoogLeNet 和 VGG 神经网络结构的时候,都看见了它们在某些层有采取 1x1 作为卷积核,起初的时候,对这个做法很是迷惑,这是因为之前 ...
- windows API 第 18篇 FindFirstVolume FindNextVolume
函数定义:Retrieves the name of a volume on a computer. FindFirstVolume is used to begin scanning the vol ...
- mysql系统变量与状态变量
一.系统变量分为全局系统变量和会话系统变量:有些变量既是全局系统变量,有些变量只有全局的,有些变量只有会话的. .变量的查询: show global variables like 'log' \G; ...
- goland破解
PyCharm是由著名的JetBrains公司所打造的一款功能强大的Python IDE,它具有一般IDE都具备的功能,并且使用起来非常方便好用.最近需求PyCharm激活码的网友非常多,小编就在这里 ...