Network of Schools --POJ1236 Tarjan
Network of Schools
Time Limit: 1000MS Memory Limit: 10000K
Description
A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the “receiving schools”). Note that if B is in the distribution list of school A, then A does not necessarily appear in the list of school B ,You are to write a program that computes the minimal number of schools that must receive a copy of the new software in order for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure that by sending the copy of new software to an arbitrary school, this software will reach all schools in the network. To achieve this goal we may have to extend the lists of receivers by new members. Compute the minimal number of extensions that have to be made so that whatever school we send the new software to, it will reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school.
Input
The first line contains an integer N: the number of schools in the network (2 <= N <= 100). The schools are identified by the first N positive integers. Each of the next N lines describes a list of receivers. The line i+1 contains the identifiers of the receivers of school i. Each list ends with a 0. An empty list contains a 0 alone in the line.
Output
Your program should write two lines to the standard output. The first line should contain one positive integer: the solution of subtask A. The second line should contain the solution of subtask B.
Sample Input
5
2 4 3 0
4 5 0
0
0
1 0
Sample Output
1
2
Source
IOI 1996
题意:学校连接到一个计算机网络,这些学校之间达成一个协议,每一个学校维护着一个学校的列表,可以向学校列表中的学校发布软件。
任务A:计算为了使每一个学校都能通过网络收到软件,至少需要准备多少份软件拷贝
任务B:要想确保在任意一个学校发放一个新的软件拷贝,所有的学校都可以接受到。必须在列表中增加新的成员,计算需要增加新成员的数目。思路:这是一个有向图,则在图中可能存在强连通分量,强连通分量中是相互连接,所以需要缩点,缩点以后会形成一个DAG图,对于一个DAG图我们只需要在入度为零的点都放上软件就可以使图中的所有点都收到软件,所以ansA为入度为零的点的数目,对于任务B则是将DAG图构成一个强连通分量,最明显的方式就是将出入为零的点与入度为零的点相连,这样就可以使DAG图变成强连通的,而增加的边的数目则要是出度为零点的数目与入度为零点的数目的最大值(自己画画就知道了)
Tarjan
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <set>
#include <algorithm>
using namespace std;
const int Max = 110;
vector <int> Map[Max];
int dfn[Max],RDu[Max],CDu[Max],low[Max],dep;
int n,num,pre[Max],vis[Max];
stack<int>S;
void init()
{
for(int i=0;i<=n;i++)
{
Map[i].clear();
}
memset(dfn,-1,sizeof(dfn));
memset(RDu,0,sizeof(RDu));
memset(CDu,0,sizeof(CDu));
memset(vis,0,sizeof(vis));
dep = 0 ; num = 0;
}
void Tarjan(int u)//求强连通分量
{
low[u]=dfn[u]=dep++;
S.push(u);
vis[u]=1;
for(int i=0;i<Map[u].size();i++)
{
if(vis[Map[u][i]]==0)
{
Tarjan(Map[u][i]);
low[u] = min(low[u],low[Map[u][i]]);
}
if(vis[Map[u][i]]==1)
{
low[u] = min(low[u],dfn[Map[u][i]]);
}
}
if(dfn[u]==low[u])
{
while(!S.empty())
{
int v = S.top();
S.pop();
pre[v] = num;
vis[v]=2;
if(v==u)
{
break;
}
}
num++;
}
}
int main()
{
while(~scanf("%d",&n))
{
init();
int v;
for(int i=1;i<=n;i++)
{
while(scanf("%d",&v)&&v)
{
Map[i].push_back(v);
}
}
for(int i=1;i<=n;i++)
{
if(dfn[i]==-1)
{
Tarjan(i);
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<Map[i].size();j++)
{
if(pre[i]!=pre[Map[i][j]])
{
CDu[pre[i]]++;
RDu[pre[Map[i][j]]]++;
}
}
}
int ansA=0,ansB=0;
for(int i=0;i<num;i++)
{
if(CDu[i]==0)
{
ansB++;
}
if(RDu[i]==0)
{
ansA++;
}
}
ansB=max(ansA,ansB);
if(num==1)//注意只有一个强连通的时候
{
ansB=0;
}
printf("%d\n%d\n",ansA,ansB);
}
return 0;
}
Kosaraju
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int Max = 110;
vector<int>GF[Max];
vector<int>GR[Max];
int path[Max],part[Max];
int RDu[Max],CDu[Max],Num;
bool vis[Max];
int n;
int ansA,ansB;
void Init()
{
for(int i=0;i<=n;i++)
{
GF[i].clear();
GR[i].clear();
}
memset(path,0,sizeof(path));
memset(part,0,sizeof(part));
memset(RDu,0,sizeof(RDu));
memset(CDu,0,sizeof(CDu));
memset(vis,false,sizeof(vis));
Num = 0; ansA = 0; ansB = 0;
}
void DFSF(int u) //正向遍历
{
if(!vis[u])
{
vis[u]=true;
for(int i=0;i<GF[u].size();i++)
{
DFSF(GF[u][i]);
}
path[++path[0]]=u;//这个一定放在遍历完子节点之后
}
}
void DFSR(int u) //反向遍历
{
if(!vis[u])
{
vis[u]=true;
part[u]=part[0];
for(int i=0;i<GR[u].size();i++)
{
DFSR(GR[u][i]);
}
}
}
void Kosaraju()
{
for(int i=1;i<=n;i++)
{
DFSF(i);
}
memset(vis,false,sizeof(vis));
for(int i=n;i>=1;i--)
{
if(!vis[path[i]])
{
++part[0];
DFSR(path[i]);
}
}
for(int i=1;i<=n;i++)//缩点,计算出入度
{
memset(vis,false,sizeof(vis));
for(int j=0;j<GF[i].size();j++)
{
if(part[i]!=part[GF[i][j]]&&!vis[part[GF[i][j]]])
{
vis[part[GF[i][j]]]=true;
CDu[part[i]]++;
RDu[part[GF[i][j]]]++;
}
}
}
for(int i=1;i<=part[0];i++)// 计算答案
{
if(RDu[i]==0)
{
ansA++;
}
if(CDu[i]==0)
{
ansB++;
}
}
ansB = max(ansA,ansB);
if(part[0]==1)
{
ansB = 0;
}
printf("%d\n%d\n",ansA,ansB);
}
int main()
{
while(~scanf("%d",&n))
{
Init();
int v;
for(int i=1;i<=n;i++)
{
while(scanf("%d",&v)&&v)
{
GF[i].push_back(v);
GR[v].push_back(i);
}
}
Kosaraju();
}
return 0;
}
Network of Schools --POJ1236 Tarjan的更多相关文章
- P2746 [USACO5.3]校园网Network of Schools// POJ1236: Network of Schools
P2746 [USACO5.3]校园网Network of Schools// POJ1236: Network of Schools 题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学 ...
- POJ1236:Network of Schools (思维+Tarjan缩点)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24880 Accepted: 99 ...
- POJ 1236 Network of Schools(Tarjan缩点)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16806 Accepted: 66 ...
- poj 1236 Network of Schools(tarjan+缩点)
Network of Schools Description A number of schools are connected to a computer network. Agreements h ...
- POJ 1236 Network of Schools (Tarjan)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22745 Accepted: 89 ...
- 洛谷 P2746 [USACO5.3]校园网Network of Schools (Tarjan,SCC缩点,DAG性质)
P2746 [USACO5.3]校园网Network of Schools https://www.luogu.org/problem/P2746 题目描述 一些学校连入一个电脑网络.那些学校已订立了 ...
- POJ 1236 Network of Schools(tarjan)
Network of Schools Description A number of schools are connected to a computer network. Agreements h ...
- POJ1236:Network of Schools(tarjan+缩点)?
题目: http://poj.org/problem?id=1236 [题意] N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1 ...
- POJ 1236 Network of Schools (tarjan算法+缩点)
思路:使用tarjan求强连通分量并进行缩点,判断所有入度为0的点,这个点就是必须要给予文件的点,分别计算出度,入度为零的点的个数,取二者的最大值就是把这个图变成强连通需要加的边数. 一个取值需要讨论 ...
随机推荐
- 兼容iOS 10 资料整理笔记
原文链接:http://www.jianshu.com/p/0cc7aad638d9 1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化 ...
- Python 打包工具cx_freeze 问题记录及解决办法
在节前的最后一天,解决了打包过程中遇到的所有问题,可以成功运行了!真是个好彩头,希望新的一年一切顺利! 以下是在使用cx_freeze过程中遇到的问题及解决办法(Win7) 问题描述:运行exe,启动 ...
- GC
垃圾回收机制的优点:释放无用的对象所占用的空间.方式:自动回收.手动回收.使用System.gc实际上是调用Runtime.getRuntime().gc()
- PDO和消息队列的一点个人理解
什么是消息队列,百度百科说,···消息队列····是在消息的传输过程中保存消息的容器. 看着网上林林总总的文章,都说是为了应对高并发,处理数据量超级大的一种数据容器,也可以说是利用各种方式,先把数据存 ...
- Python之路-(Django进阶二)
model: 双下划线: # 获取个数 # # models.Tb1.objects.filter(name='seven').count() # 大于,小于 # # models.Tb1.objec ...
- csuoj 1119: Collecting Coins
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1119 1119: Collecting Coins Time Limit: 3 Sec Memo ...
- 【VirtualBox】 Failed to open/create the internal network 'HostInterfaceNetworking-VirtualBox Host
win10 VirtualBox_5.0.24.8355_Win 安装后导入.ova 文件后 虚拟机不能正常启动 ===> 解决: “打开网络和共享中心” “更多适配器设置” 选择 对应的网络适 ...
- GetKeyboardType获取键盘类型(通过键盘可初步判断用户使用的是台式电脑还是笔记本电脑)
函数功能:该函数获取系统当前键盘的信息. int WINAPI GetKeyboardType( __in int nTypeFlag ); 参数说明:nTypeFlag:指定要获取的键盘信息的类型, ...
- matlab画带标记的折线图
1.不带标记的 如: x=[1,5,3,7,4] plot(x) 2. 带标记 plot(x,'-*') '-s' 表示方格 '-p' 表示五角星 '-d' 表示菱形 '-h' 表示六角形 '-+' ...
- 亲手使用Sencha Touch + phonepag开发Web APP随笔 -- 第一个APP
参考博文: [Phonegap+Sencha Touch] 移动开发1.准备工作 [Phonegap+Sencha Touch] 移动开发2.PhoneGap/Cordova初步使用 经过差不多1 ...