POJ 1236 学校网络间的强连通

题目大意:

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

链接http://vjudge.net/problem/viewProblem.action?id=17001

每个强连通分量内只要有任意一个学校获得一份软件就可以了,因为强连通分量内的任意两点是相互可达的。

也就是说,在一个强联通分量内的学校可以当作一个学校!

那么第一问我们所求的就是强连通分量重入度为零的点

而第二问因为两个强连通合并必然是出度为0的连接入度为0的点,所以要解决掉入度为0,和出度为0的点,所以答案是这两个的最大值(点指缩点)。

利用scc[i]=scc_cnt 来记录i这个点属于scc_cnt这个连通分量

总代码如下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
#define N 105
int first[N],scc[N],dfn[N],low[N],degreeIn[N],degreeOut[N],k,n,tmpdfn,scc_cnt;
stack<int> q;
struct Path{
    int y,next;
}path[100005];
void init()
{
    memset(first,-1,sizeof(first));
    memset(dfn,0,sizeof(dfn));
    memset(degreeIn,0,sizeof(degreeIn));
    memset(degreeOut,0,sizeof(degreeOut));
    memset(scc,0,sizeof(scc));
    scc_cnt=0,tmpdfn=0,k=0;
}
void add(int x,int y)
{
    path[k].y=y,path[k].next=first[x];
    first[x]=k;
    k++;
}
void dfs(int u)
{
    dfn[u]=low[u]=++tmpdfn;
    q.push(u);
    for(int i=first[u];i!=-1;i=path[i].next){
        int v=path[i].y;
        if(!dfn[v]){
            dfs(v);
            low[u]=min(low[v],low[u]);
        }
        else if(!scc[v]) low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u]){
        scc_cnt++;
        for(;;){
            int v=q.top(); q.pop();
            scc[v]=scc_cnt;
            if(u==v) break;
        }
    }
}
void get_scc()
{
    while(!q.empty()) q.pop();
    for(int i=1;i<=n;i++)
        if(!dfn[i]) dfs(i);
    //cout<<"OK"<<endl;
    for(int i=1;i<=n;i++){
        for(int j=first[i];j!=-1;j=path[j].next){
            int v=path[j].y;
            //cout<<v<<endl;
            if(scc[i]!=scc[v]){
                degreeOut[scc[i]]++;
                degreeIn[scc[v]]++;
            }
        }
    }
}
int main()
{
    int i,a;
    while(~scanf("%d",&n)){
        int ans1=0,ans2=0;
        init();
        for(i=1;i<=n;i++){
            while(scanf("%d",&a) && a) add(i,a);
        }
        get_scc();
        //for(int i=1;i<=scc_cnt;i++) cout<<degreeIn[i]<<endl;
        //cout<<scc_cnt<<endl;
        for(int i=1;i<=scc_cnt;i++){
            if(!degreeOut[i]) ans1++;
            if(!degreeIn[i]) ans2++;
        }
        ans1=max(ans1,ans2);
        //cout<<"Á¬Í¨·ÖÁ¿£º"<<cnt<<endl;
        if(scc_cnt>1){
            printf("%d\n",ans2);
            printf("%d\n",ans1);
        }
        else printf("1\n0\n");
    }
    return 0;
}

POJ 1236 学校网络间的强连通

时间: 2024-08-29 03:43:46

POJ 1236 学校网络间的强连通的相关文章

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

POJ 1236 Network of Schools 有向图强连通分量

参考这篇博客: http://blog.csdn.net/ascii991/article/details/7466278 #include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> #include <vector> #include <stack> using namespace std; typedef long long LL; c

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

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

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 【强连通图】

题目: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对强连通分量进行缩点,然后对缩点以后的图进行处理,统计图中节点出度为零的有多少,入度为零的有多少个? 因为入度为零的点不能由其他的点到达,在每个入度为零的节点安装网络可

POJ 1236 Network of Schools - 缩点

POJ 1236 :http://poj.org/problem?id=1236 参考:https://www.cnblogs.com/TnT2333333/p/6875680.html 题意: 有好多学校,每个学校可以给其他特定的学校发送文件.第一个问题是最少要给几个学校发文件,可以使得全部的学校收到文件.第二个问题是最少要加几条线路,使得随意挑一个学校发文件,也能使得全部的学校收到文件. 思路: 第一个问题,可以用tarjan给图中先缩点,因为强连通的环相互可达.所以只要数出缩完点后图中入度

ZOJ1372 POJ 1287 Networking 网络设计 Kruskal算法

题目链接:ZOJ1372 POJ 1287 Networking 网络设计 Networking Time Limit: 2 Seconds      Memory Limit: 65536 KB You are assigned to design network connections between certain points in a wide area. You are given a set of points in the area, and a set of possible