`
Simone_chou
  • 浏览: 192513 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

校园网络(强连通分量)

    博客分类:
  • NYOJ
 
阅读更多

校园网络

时间限制:3000 ms  |  内存限制:65535 KB
难度:5
 
描述

南阳理工学院共有M个系,分别编号1~M,其中各个系之间达成有一定的协议,如果某系有新软件可用时,该系将允许一些其它的系复制并使用该软件。但该允许关系是单向的,即:A系允许B系使用A的软件时,B未必一定允许A使用B的软件。

现在,请你写一个程序,根据各个系之间达成的协议情况,计算出最少需要添加多少个两系之间的这种允许关系,才能使任何一个系有软件使用的时候,其它所有系也都有软件可用。

 
输入
第一行输入一个整数T,表示测试数据的组数(T<10)
每组测试数据的第一行是一个整数M,表示共有M个系(2<=M<=100)。
随后的M行,每行都有一些整数,其中的第i行表示系i允许这几个系复制并使用系i的软件。每行结尾都是一个0,表示本行输入结束。如果某个系不允许其它任何系使用该系软件,则本行只有一个0.
输出
对于每组测试数据,输出最少需要添加的这种允许关系的个数。
样例输入
1
5
2 4 3 0
4 5 0
0
0
1 0
样例输出
2

 

      思路:

      强连通分量缩点后,再找入度为0的节点数 和 出度为0的节点数 的最大值即可。

 

      AC:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>

using namespace std;

const int VMAX = 105;

int in[VMAX], out[VMAX];
vector<int> G[VMAX];
int n;

int dfs_clock, scc_cnt;
int pre[VMAX], cmp[VMAX], low[VMAX];
stack<int> s;

void dfs (int u) {
    low[u] = pre[u] = ++dfs_clock;
    s.push(u);

    for (int i = 0; i < G[u].size(); ++i) {
        int v = G[u][i];
        if (!pre[v]) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if (!cmp[v]) {
            low[u] = min(low[u], pre[v]);
        }
    }

    if (pre[u] == low[u]) {
        ++scc_cnt;
        for ( ;;) {
            int x = s.top(); s.pop();
            cmp[x] = scc_cnt;
            if (x == u) break;
        }
    }
}

void scc() {
    scc_cnt = dfs_clock = 0;
    memset(cmp, 0, sizeof(cmp));
    memset(pre, 0, sizeof(pre));

    for (int i = 1; i <= n; ++i) {
        if (!pre[i]) dfs(i);
    }
}

int main() {

    int t;
    scanf("%d", &t);

    while (t--) {
        scanf("%d", &n);

        for (int i = 1; i <= n; ++i) {
            G[i].clear();
            in[i] = out[i] = 0;
        }

        for (int i = 1; i <= n; ++i) {
            int num;
            while (~scanf("%d", &num) && num) {
                G[i].push_back(num);
            }
        }

        scc();

        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j < G[i].size(); ++j) {
                int v = G[i][j];
                ++in[ cmp[v] ];
                ++out[ cmp[i] ];
            }
        }

        int in_num = 0, out_num = 0;
        for (int i = 1; i <= scc_cnt; ++i) {
            if (!in[i]) ++in_num;
            if (!out[i]) ++out_num;
        }

        printf("%d\n", max(in_num, out_num));
    }

    return 0;
}

 

 

分享到:
评论

相关推荐

    求有向图的强连通分量

    有向图的强连通分量是图论中的一个重要概念,...总之,有向图的强连通分量是图论中的重要概念,它在许多实际问题中都有应用,例如网络分析、任务调度等。通过理解并掌握求解强连通分量的算法,可以有效地解决这类问题。

    强连通分量Kosaraju算法

    强连通分量是图论中的一个重要概念,特别是在有向图中。在有向图中,如果两个顶点之间存在双向路径(即从一个顶点可以到达另一个顶点,反过来也一样),则这两个顶点被视为属于同一个强连通分量。强连通分量是图的...

    有向图的强连通分量课程设计报告.docx

    有向图的强连通分量是图论中的一个重要概念,尤其在算法设计和数据结构的学习中占有举足轻重的地位。本课程设计报告主要针对有向图的强连通分量进行深入研究,通过算法分析和系统设计,实现求解有向图强连通分量的...

    求有向图的强连通分量(scc)Tarjan算法.docx

    在实际应用中,Tarjan算法常用于解决网络拓扑结构、社交网络分析、数据挖掘等领域中的强连通分量问题。 Tarjan算法的C++实现代码如下: ```cpp #include #include using namespace std; const int MAX=10001; ...

    有向图的强连通分量的求解

    ### 有向图的强连通分量求解方法 #### 一、基本概念与定义 **有向图**:由一系列顶点及其之间的有向边组成的图形称为有向图。有向图中的边是有方向的,即从一个顶点指向另一个顶点。 **强连通分量**:如果一个有...

    求强连通分量---模板(K算法)

    ### 求强连通分量——模板(Kosaraju算法) #### 一、引言 在图论中,有向图中的强连通分量是指图中的一个子集,其中任意两个顶点都是相互可达的。求解强连通分量是图论中的一个重要问题,对于理解图的结构具有...

    强连通分量函数.c

    强连通分量函数.c

    图中强连通分量的寻找

    在实际应用中,强连通分量的概念广泛应用于网络分析、社交网络、编译器设计等领域。例如,在社交网络中,强连通分量可能表示一组用户,他们相互之间都有联系,形成紧密的小团体。在编译器中,控制流图的强连通分量...

    Tarjan算法求强连通分量

    使用Tarjan算法进行快速计算强连通分量,C++语言实现。

    Tarjan 的强连通分量算法的Python实现

    )图作为输入,并以拓扑顺序返回其强连通分量作为输出 循环依赖 在各种情况下,依赖关系可能是循环的,并且必须同时执行一组相互依赖的操作。同时执行成本高昂的情况并不少见。使用 Tarjan 算法,可以确定执行相互...

    强连通分量的Kosaraju算法实现

    2. 用Kosaraju算法实现了强连通分量的求解。其中data中包含的GoolNodes测试集为Google提供的网页之间的连接经转化而来,每一个结点均代表一个网页。 3. 缺点:为了使用以前的CGraph类,强行添加了结点文件,其中第一...

    双连通分量和强连通分量

    trajan gabow Kosaraju 双连通分量和强连通分量 希望对大家有助

    用python求取强连通分量个数

    用python求取强连通分量个数 假设我们有一个有向图,其顶点和边如下所示: 顶点:0,1,2,3,4,5,6,7 边:(0→1,(1→2),(2→0),(2→3),(3→4),(4→5),(5→3),(5→6),(6→4),(6→7) 接下来,我将编写一个...

    无向图的强连通分量.cpp

    无向图的强连通分量(1).cpp //这个是内网比赛的代码,用到了无向图的双连通分量 ,gabow部分是求双联通的

    一个很好的强连通分量的课件

    强连通分量是图论中的一个重要概念,特别是在有向图中。一个强连通图指的是对于图中任意两个顶点v和u,都存在从v到u的有向路径,同时也存在从u到v的有向路径。而强连通分量则是有向图中的一个子集,其中的每个顶点都...

    有向图的强连通分量

    详细地介绍了如何计算强连通分量,图文并茂地阐述了tarjan算法的流程和原理,两者均有模板。

    有向图强联通分量求解代码

    ### 有向图强联通分量求解代码详解 #### 引言 在图论中,有向图的强连通性是一个重要的概念。如果一个有向图中的任意两个顶点都相互可达,则称该图是强连通的。强连通分量是指在一个有向图中最大的、自身内部任何两...

    强连通分量(Strongly Connected Components)查找 原理熟悉,深度搜索,小白入手无压力

    强连通分量个数怎么求?用小白都能理解的C语言去解答这个问题最合适不过。 原理熟悉,深度搜索,小白入手无压力 强连通分量(Strongly Connected Components,简称SCC)是图论中的一个概念,用于描述有向图中的一组...

    数据结构课程设计报告--实现求有向图强连通分量的算法

    在键盘上输入有向图,对任意给定的图(顶点数和边数自定),建立它的邻接表并输出。然后判断该图是否强连通。如果是强连通图,求出该图的所有强连通分量并输出字符

Global site tag (gtag.js) - Google Analytics