poj 1236 Network of Schools 【强连通图】

题目:poj 1236 Network of Schools

类似题目hdoj 2767 3836

/*******以下kuang大神的解释,写的很好就不解释了*************************/

强连通分量缩点求入度为0的个数和出度为0的分量个数

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

 

也就是:

—        给定一个有向图,求:

 

1) 至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点

 

2) 至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点

 

—        顶点数<= 100

解题思路:

—        1. 求出所有强连通分量

—        2. 每个强连通分量缩成一点,则形成一个有向无环图DAG。

—        3. DAG上面有多少个入度为0的顶点,问题1的答案就是多少

在DAG上要加几条边,才能使得DAG变成强连通的,问题2的答案就是多少

加边的方法:

要为每个入度为0的点添加入边,为每个出度为0的点添加出边

假定有 n 个入度为0的点,m个出度为0的点,如何加边?

把所有入度为0的点编号 0,1,2,3,4 ....N -1

每次为一个编号为i的入度0点可达的出度0点,添加一条出边,连到编号为(i+1)%N 的那个出度0点,

这需要加n条边

若 m <= n,则

加了这n条边后,已经没有入度0点,则问题解决,一共加了n条边

若 m > n,则还有m-n个入度0点,则从这些点以外任取一点,和这些点都连上边,即可,这还需加m-n条边。

所以,max(m,n)就是第二个问题的解

此外:当只有一个强连通分支的时候,就是缩点后只有一个点,虽然入度出度为0的都有一个,但是实际上不需要增加清单的项了,所以答案是1,0;

AC代码Hdoj3676:

#include <cstdio>
#include <vector>
#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
const int N = 25000;
vector<int> G[N];
int pre[N],lowlink[N],sccno[N],dfs_clock,scc_cnt; //sccno【i】 i所在的scc图的编号
//scc_cnt 联通块的数量
stack<int> s;

void dfs(int u)
{
    pre[u] = lowlink[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);
            lowlink[u]=min(lowlink[u],lowlink[v]);
        }
        else if(!sccno[v])
        {
            lowlink[u]=min(lowlink[u],pre[v]);
        }
    }
    if(lowlink[u]==pre[u])
    {
        scc_cnt++;
        for(;;)
        {
            int x=s.top();
            s.pop();
            sccno[x]=scc_cnt;
            if(x==u)
                break;
        }
    }
}
void find_scc(int n)
{
    dfs_clock=scc_cnt=0;
    memset(sccno,0,sizeof(sccno));
    memset(pre,0,sizeof(pre));
    for(int i=0; i<n; i++)
        if(!pre[i]) dfs(i);
}
int in[N],out[N];
int workout(int n) {
    if (scc_cnt == 1)
        return 0;
    memset(in, 0, sizeof(int)*(n+1));
    memset(out, 0, sizeof(int)*(n+1));
    for (int u = 0; u < n; u++) {
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            if (sccno[u] != sccno[v]) {
                in[sccno[v]] += 1;
                out[sccno[u]] += 1;
            }
        }
    }
    int c1 = 0, c2 = 0;
    for (int i = 1; i <= scc_cnt; i++) {
        if (in[i] == 0) c1 += 1;
        if (out[i] == 0) c2 += 1;
    }
    return max(c1, c2);
}
int main()
{
    int n,m,T;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            G[x-1].push_back(y-1);
        }
        find_scc(n);
        printf("%d\n",workout(n));
        for(int i=0;i<n;i++)
            G[i].clear();
    }
    return 0;
}

时间: 2024-12-20 22:47:30

poj 1236 Network of Schools 【强连通图】的相关文章

POJ 1236 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 if B is in the

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 (Tarjan)

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

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

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

[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 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1236 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: e

poj 1236 Network of Schools(tarjan+缩点)

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

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

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