Network of Schools POJ - 1236 (强联通)
一些学校连接到了一个计算机网络。网络中的学校间有如下约定:每个学校维护一个列表,当该学校收到软件或信息后将会转发给列表中的所有学校(也就是接收方列表)。需要注意的是如果B学校在A学校的接收方列表中,A学校不一定会出现在B学校的接收方列表中。
你现在的任务是写出一个程序来计算必须收到一份软件来使网络中的所有学校都能收到软件的学校的数量的最小值(此为子任务A)。作为一个远期目标,我们希望给任意一个学校发送一份软件都能使网络中的所有学校都收到软件。为了实现这个目标,我们或许需要在一些学校的接收方列表中添加新项。 你现在需要计算出至少需要添加多少新项才能实现这个远期目标(此为子任务B)。
Input
第一行是一个整数N:计算机网络中的学校数量(2<=N<=100)。接下来有N行数据,接下来的第 i 行描述了第 i 个学校的接收方列表。每行列表以0结尾。如果第 j 行中只有一个0代表第 j 个学校的接收方列表是空的。
Output
你的程序应该在标准输出中输出两行。每一行应为一个整数:第一行为子任务A的解,第二行为子任务B的解。
Sample Input
| 5 2 4 3 0 4 5 0 0 0 1 0 |
|---|
Sample Output
| 1 2 |
|---|
首先缩点,查看有几个强连通图,查看缩点后的DAG(有向无环图)入度为0和出度为0的多少,选取其中最大值。
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
const int MAXN=1001;
struct node{
int v,next;
}edge[MAXN*10];
int dfn[MAXN],low[MAXN];
int head[MAXN],cnt,belong[MAXN];
bool vis[MAXN];
int tim;
stack<int >st;
int out[MAXN],in[MAXN];
int num=0;
void tarjan(int u)
{
dfn[u]=low[u]=++tim;
vis[u]= true;
st.push(u);
for (int i = head[u]; i !=-1 ; i=edge[i].next) {
if(!dfn[edge[i].v]) {
tarjan(edge[i].v);
low[u]=min(low[u],low[edge[i].v]);
}
else if(vis[edge[i].v]){
low[u]=min(low[u],dfn[edge[i].v]);
}
}
if(dfn[u]==low[u])
{
int x;
++num;
while(1)
{
x=st.top();
st.pop();
vis[x]=0;
belong[x]=num;
if(x==u)break;
}
}
}
void add(int x,int y)
{
edge[++cnt].next=head[x];
edge[cnt].v=y;
head[x]=cnt;
return ;
}
void slove(int n)
{
for (int i = 1; i <=n ; ++i) {
if(dfn[i]==0) tarjan(i);
}
for (int j = 1; j <=n ; ++j) {
for (int k = head[j]; k !=-1 ; k=edge[k].next) {
int v=edge[k].v;
if(belong[j]!=belong[v]) {
out[belong[j]]++;
in[belong[v]]++;
}
}
}
int ans1=0,ans2=0;
for (int i = 1; i <=num ; ++i) {
if(in[i]==0)ans1++;
if(out[i]==0) ans2++;
}
ans2=max(ans1,ans2);
if(num==1)printf("1\n0\n");
else
printf("%d\n%d\n",ans1,ans2);
}
int main()
{
int n;
scanf("%d",&n);
int x;
cnt=0;
memset(head,-1, sizeof(head));
for (int i = 1; i <=n ; ++i) {
while (scanf("%d",&x)&&x) {
add(i,x);
}
}
slove(n);
return 0;
}
Network of Schools POJ - 1236 (强联通)的更多相关文章
- poj 1236 强联通分量
大致题意给你有一个点数为n<=100的有向图. 求解两个子任务: 1:最少给多少个点信息,这些点的信息可以顺着有向边传遍全图. 2:最少要加多少条边,使得整个图强联通. 求强联通分量再缩点后得到 ...
- A - Network of Schools - poj 1236(求连通分量)
题意:学校有一些单向网络,现在需要传一些文件,1,求最少需要向几个学校分发文件才能让每个学校都收到,2,需要添加几条网络才能在任意一个学校分发都可以传遍所有学校. 分析:首先应该求出来连通分量,进行缩 ...
- Network of Schools POJ - 1236(强连通+缩点)
题目大意 有N个学校,这些学校之间用一些单向边连接,若学校A连接到学校B(B不一定连接到A),那么给学校A发一套软件,则学校B也可以获得.现给出学校之间的连接关系,求出至少给几个学校分发软件,才能使得 ...
- Network of Schools POJ - 1236 有向强连通图
//题意://给你n个学校,其中每一个学校都和一些其他学校有交流,但是这些边都是单向的.你至少需要给几个学校//传递消息可以使全部学校都收到消息,第二问你最少添加几条边可以使它变成一个强连通图//题解 ...
- POJ 1236-Network of Schools (图论-有向图强联通tarjan)
题目链接:http://poj.org/problem?id=1236 题目大意:N(2<N<100)个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输.问题 ...
- POJ 2186 强联通分量
点击打开链接 题意:牛A喜欢牛B,若牛B喜欢牛C,则牛A喜欢牛C,问最后多少牛被其它全部牛喜欢 思路:用强联通分量进行缩点,最后形成的图是有向无环图DAG.而拓扑序的值为DAG的长度,则加一,可是最后 ...
- 【POJ 1236 Network of Schools】强联通分量问题 Tarjan算法,缩点
题目链接:http://poj.org/problem?id=1236 题意:给定一个表示n所学校网络连通关系的有向图.现要通过网络分发软件,规则是:若顶点u,v存在通路,发给u,则v可以通过网络从u ...
- poj 1236 Network of Schools(连通图入度,出度为0)
http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Su ...
- poj 1236 Network of Schools(又是强连通分量+缩点)
http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Su ...
随机推荐
- DockerSwarm 微服务部署
一.简介 之前<服务Docker化>中,使用 docker-compose.yml 来一次配置启动多个容器,在 Swarm 集群中也可以使用 compose 文件 (docker-comp ...
- hibernate课程 初探单表映射2-4 transaction简介
1 hibernate是非自动提交.如果transaction不写的话,会只创建表结构而不插入语句. 如果不写transaction而想实现插入的功能的话,需要重写session的dowork方法 ...
- Vue2.0搭建脚手架(vue-cli)
一.安装node.js 进入官网下载node.js 二.安装 cnpm 1.说明:npm(node package manager)是nodejs的包管理器,用于node插件管理(包括安装.卸载.管理 ...
- Linux命令行环境与桌面环境护切换
1.前言 在大部分情况下,我们在使用Linux时习惯使用命令行环境,但是有时候也还是会使用到安装桌面环境,所以在这里介绍一下如何给没有安装桌面环境的系统安装桌面环境.以Centos 6.5 为例演示一 ...
- SpringBoot的快速构建
1.http://start.spring.io2.Spring Tool Suite3.IntelliJ IDEA4.Spring Boot CLI5.Maven手工构建
- CheckPoint_vSEC_Cluster_R77.30
CheckPoint_vSEC_Cluster_R77.30 平台: arm 类型: ARM 模板 软件包: Check Point vSEC Gateway R77.30-041.161 Anti- ...
- Oracle添加自增长字段方法步骤
第一步:创建自增长序列 CREATE SEQUENCE ZH_ALARM_INFO_SEQ--自动增长列 INCREMENT BY 1 -- 每次加几个 START WITH 1 -- 从1开始计数 ...
- bootstrap table保留多选框的分页
有时候需要完成这种情况: 1.需要设置的是如果第一页点击复选框然后点击其他页面的话,第一页的选项被保存了 2.将所有选择好的复选款的数据保存在数组中 bootstrap table官方文档http:/ ...
- Java 使用正则表达式取出图片地址以及跳转的链接地址,来判断死链(一)
任务:通过driver的getPageSource()获取网页的源码内容,在把网页中图片链接地址和跳转的url地址进行过滤,在get每个请求,来判断是否是死链 如图: 获取网页源码中所有的href,以 ...
- python_67_生成器3
import time def consumer(name): print("%s 准备吃包子啦!"%name) while True: baozi = yield print(& ...