POJ 1236-Network of Schools (图论-有向图强联通tarjan)

题目链接:http://poj.org/problem?id=1236

题目大意:N(2<N<100)个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输。
问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。
问题2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。

解题思路:首先用tarjan求得所有强联通分量,将每个强联通分量看成一个点,这样会得到一个有向无环图DAG, 那么对于问题一只需要要找出DAG图上有多少个入度为0的点,对于问题二需要在DAG图上找出度为0的点的个数, 然后与问题一入度为0的点的个数取最大值, 就是问题二的答案。

需要注意的是只有一个强联通分量的时候, 需要特判一下。

代码如下:

#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 103;

vector<int>vec[N], stk;
bool mp[N][N], in_stk[N];
int low[N], dfn[N], tot, cou_scc;
int belong[N];
int n;

void tarjan(int u, int f)
{
    dfn[u] = low[u] = tot ++;
    stk.push_back(u), in_stk[u] = true;
    for(int i=0; i < vec[u].size(); ++ i)
    {
        int v = vec[u][i];
        if(dfn[v] == -1)
        {
            tarjan(v, u);
            low[u] = min(low[u], low[v]);
        }
        else if(in_stk[v])
            low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u])
    {
        ++ cou_scc;
        while(1)
        {
            int v = stk.back();
            stk.pop_back();
            in_stk[v] = false;
            belong[v] = cou_scc;
            if(u == v)
                break;
        }
    }
}

int main()
{
    while(scanf("%d", &n) != EOF)
    {
        memset(mp, false, sizeof(mp));
        for(int i=1; i<=n; ++ i)
        {
            vec[i].clear();
            int c;
            while(scanf("%d", &c), c)
            {
                vec[i].push_back(c);
                mp[i][c] = true;
            }
        }
        memset(low, -1, sizeof(low));
        memset(dfn, -1, sizeof(dfn));
        memset(belong, -1, sizeof(belong));
        memset(in_stk, false, sizeof(in_stk));
        cou_scc = 0, tot = 1;
        stk.clear();
        for(int i=1; i<=n; ++ i)
        {
            if(dfn[i] == -1)
                tarjan(i, -1);
        }
        int in[N], out[N];
        memset(in, 0, sizeof(in));
        memset(out, 0, sizeof(out));
        for(int i=1; i<=n; ++ i)
        {
            for(int j=1; j<=n; ++ j)
            {
                if(mp[i][j] && belong[i] != belong[j])
                {
                    ++ in[belong[j]];
                    ++ out[belong[i]];
                }
            }
        }
        if(cou_scc == 1)
        {
            printf("1\n0\n");
            continue;
        }
        int x = 0, y = 0;
        for(int i=1; i<=cou_scc; ++ i)
        {
            if(in[i] == 0)
                ++ x;
            if(out[i] == 0)
                ++ y;
        }
        printf("%d\n%d\n", x, max(x, y));
    }
}

时间: 2024-12-21 18:38:12

POJ 1236-Network of Schools (图论-有向图强联通tarjan)的相关文章

POJ - 1236 Network of Schools(有向图的强连通分量)

d.各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输, 问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件. 问题2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件.s.首先找强连通分量,然后看强连通分量的入度为0点的总数,出度为0点的总数. 第一问为入度为0的强连通分量的个数. 第二问为入度为0的个数和出度为0的个数中大的.(将这个图的所有子树找出来,然后将一棵子树的叶子结

POJ 3180-The Cow Prom (图论-有向图强联通tarjan算法)

题目大意:有n个牛在一块, m条单项绳子, 有m个链接关系, 问有多少个团体内部任意两头牛可以相互可达 解题思路:有向图强连通分量模版图 代码如下: #include<stdio.h> #include<vector> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long ll; const int N = 10003; vec

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

POJ 1236 Network of Schools 链接:http://poj.org/problem?id=1236 题意:有一些学校连接到一个计算机网络.这些学校之间达成了一个协议:每个学校维护着一个学校列表,它向学校列表中的学校发布软件.注意,如果学校B 在学校A 的列表中,则A 不一定在B 的列表中. 任务A:计算为使得每个学校都能通过网络收到软件,你至少需要准备多少份软件拷贝. 任务B:考虑一个更长远的任务,想确保给任意一个学校发放一个新的软件拷贝,该软件拷贝能发布到网络中的每个学

POJ 1236 Network of Schools(强连通 Tarjan+缩点)

POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意: 给定一张有向图,问最少选择几个点能遍历全图,以及最少加入?几条边使得有向图成为一个强连通图. 分析: 跟HDU 2767 Proving Equivalences(题解)一样的题目,只是多了个问题,事实上转化成DAG后就不难考虑了,事实上仅仅要选择入度为0的点即可了. 代码: /* * Author: illuz <iilluzen[at]gmail.com> *

poj 1236 Network of Schools 【强连通图】

题目:poj 1236 Network of Schools 类似题目hdoj 2767 3836 /*******以下kuang大神的解释,写的很好就不解释了*************************/ 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件.2,至少需要添加几条传输线路(边),使任

Poj 1236 Network of Schools (Tarjan)

题目链接: Poj 1236 Network of Schools 题目描述: 有n个学校,学校之间有一些单向的用来发射无线电的线路,当一个学校得到网络可以通过线路向其他学校传输网络,1:至少分配几个网络才能够让所有学校被网络覆盖?2:至少要加几条线路就能做到在任意一个学校安装网络都可以覆盖全部学校? 解题思路: 先用Tarjan对强连通分量进行缩点,然后对缩点以后的图进行处理,统计图中节点出度为零的有多少,入度为零的有多少个? 因为入度为零的点不能由其他的点到达,在每个入度为零的节点安装网络可

[tarjan] poj 1236 Network of Schools

题目链接: http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11433   Accepted: 4551 Description A number of schools are connected to a computer network. Agreements have been developed among thos

poj 1236 Network of Schools(连通图入度,出度为0)

http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13046   Accepted: 5215 Description A number of schools are connected to a computer network. Agreements have been developed among those scho

POJ 1236 Network of Schools(强联通缩点)

Network of Schools 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