POJ1236 Network of Schools (强连通分量,注意边界)

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

1,一个有向图,问最少选择几个点做源头,使得可以通过它们到达所以点(一个点可以到达任意多个后序点)------求入度为0的点数。

2,一个有向图,问最少加几条边后强连通------求max(入度为0的点数,出度为0的点数),之前证明过。但是需要注意已经强连通的情况下会出错(需要特判)。

3,一个有向图,问最少选择几个点做源头,使得可以通过它们到达所以点(一个点可以到达一个后序点)------缩点后用最小路径覆盖(二分图匹配)

此题只求1,2两个问,一定要注意特判。

//有向图缩点 ,注意scc_cnt=1时。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=210;
int Laxt[maxn],Next[maxn*200],To[maxn*200],cnt,n;
int dfn[maxn],low[maxn],times,scc_cnt,scc[maxn];
int instc[maxn],stc[maxn],top,ans1,ans2;
int ind[maxn],oud[maxn];
void update()
{
    cnt=times=scc_cnt=top=ans1=ans2=0;
    memset(Laxt,0,sizeof(Laxt));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(scc,0,sizeof(scc));
    memset(instc,0,sizeof(instc));
    memset(stc,0,sizeof(stc));
    memset(ind,0,sizeof(ind));
    memset(oud,0,sizeof(oud));
}
void add(int u,int v)
{
    Next[++cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
}
void dfs(int u)
{
    dfn[u]=low[u]=++times;
    stc[++top]=u; instc[u]=1;
    for(int i=Laxt[u];i;i=Next[i]){
        int v=To[i];
        if(!dfn[v]){
            dfs(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instc[v]){
            low[u]=min(low[u],dfn[v]);
        }
    }
    if(dfn[u]==low[u]){
        scc_cnt++;
        while(true){
            int x=stc[top--];
            scc[x]=scc_cnt;
            instc[x]=0;
            if(x==u) break;
        }
    }
}
void tarjan()
{
    for(int i=1;i<=n;i++)
        if(!dfn[i]) dfs(i);
    for(int i=1;i<=n;i++)
      for(int j=Laxt[i];j;j=Next[j]){
        if(scc[i]!=scc[To[j]]) {
            ind[scc[To[j]]]++;
            oud[scc[i]]++;
        }
    }

    for(int i=1;i<=scc_cnt;i++){
        if(ind[i]==0) ans1++;
        if(oud[i]==0) ans2++;
    }
}
int main()
{
    while(~scanf("%d",&n)){
        update();
        for(int i=1;i<=n;i++) {
            int x; while(scanf("%d",&x)){
                if(x==0) break;
                add(i,x);
            }
        }
        tarjan();
        if(scc_cnt==1) printf("1\n0\n");
        else printf("%d\n%d\n",ans1,ans2);
    } return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/8440697.html

时间: 2024-10-12 17:11:57

POJ1236 Network of Schools (强连通分量,注意边界)的相关文章

[IOI1996] USACO Section 5.3 Network of Schools(强连通分量)

nocow上的题解很好. http://www.nocow.cn/index.php/USACO/schlnet 如何求强连通分量呢?对于此题,可以直接先用floyd,然后再判断. ---------------------------------------------------------------------------------- #include<cstdio> #include<iostream> #include<algorithm> #includ

Network of Schools(强连通分量+缩点) (问添加几个点最少点是所有点连接+添加最少边使图强连通)

Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13801   Accepted: 5505 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a li

POJ - 1236 Network of Schools(强连通分量)

题目大意:有N个点,接着给出N个点所能连接的点. 问题1:如果要将一个信息传递给这N个点,至少需要传递给多少个点,然后让这些点进行传播,使N个点都得到信息 问题2:需要添加多少条边才能使这N个点能两两连通 解题思路:求出所有的强连通分量,接着缩点,再以桥为路径,建图 找出这张图中入度为0的,因为只有入度为0的才需要进行通知,其他的点可以通过其他边进行传达 需要添加多少个点,观察这张图,求出每个点的出度和入度,取max(入度为零的点的数量,出度为0的点数量) 注意当强连通分量只有1个的时候 #in

POJ 1236 Network of Schools(强连通分量)

题目地址:POJ 1236 这个题的大意是求最少往多少点发送消息可以使任意一个点都能收到消息和最少增加多少条边可以使图为连通图.对于第一个问题,可以求入度为0的强连通块的块数,因为只有入度为0的强连通块是无法从外界接受信息的,而只要有一个入度的话,那整个连通块就都可以接收到信息.第二个问题则是求入度为0的强连通块与出度为0的强连通块的个数的最大值. 代码如下: #include <iostream> #include <cstdio> #include <string>

POJ 1236 Network Of Schools (强连通分量模板题)

代码: #include<iostream> #include<cstdio> #include<cmath> #include<map> #include<queue> #include<vector> #include<cstring> #include<algorithm> #define rep(i,a,b) for(int i=(a);i<(b);i++) #define rev(i,a,b)

POJ 1236 Network of Schools (强连通分量缩点求度数)

题意: 求一个有向图中: (1)要选几个点才能把的点走遍 (2)要添加多少条边使得整个图强联通 分析: 对于问题1, 我们只要求出缩点后的图有多少个入度为0的scc就好, 因为有入度的scc可以从其他地方到达. 对于问题2, 每个入度为0的scc, 都可以补一条边可以变成强连通图, 每个出度为0的scc, 也可以补一条边使其变成强连通图. 所以答案就是max(入度为0scc个数,出度为0scc个数). #include<cstdio> #include<iostream> #inc

poj1236 Network of Schools ,求强连通分量(Tarjan算法),缩点

题目链接: 点击打开链接 题意: 给定一个有向图,求: 1) 至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 2) 至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点 顶点数<= 100 求完强连通分量后,缩点,计算每个点的入度,出度. 第一问的答案就是入度为零的点的个数, 第二问就是max(n,m) // 入度为零的个数为n, 出度为零的个数为m. //kuangbin巨巨分析很棒! #include<cstdio> #include<cstring>

P2746 [USACO5.3]校园网Network of Schools// POJ1236: Network of Schools

P2746 [USACO5.3]校园网Network of Schools// POJ1236: Network of Schools 题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”).注意即使 B 在 A 学校的分发列表中, A 也不一定在 B 学校的列表中. 你要写一个程序计算,根据协议,为了让网络中所有的学校都用上新软件,必须接受新软件副本的最少学校数目(子任务 A).更进一步,我们想要确定通过给任意一个学校发送新软件,这个

【连通图|强连通分量+缩点】POJ-1236 Network of Schools

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 softwa