ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[USACO5.3]校园网Network of Schools

2021-10-07 10:00:42  阅读:175  来源: 互联网

标签:学校 int USACO5.3 stk Schools dfn low 校园网 include


一些学校连入一个电脑网络。那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”)。

注意即使 B 在 A学校的分发列表中,A 也不一定在 B 学校的列表中。

你要写一个程序计算,根据协议,为了让网络中所有的学校都用上新软件,必须接受新软件副本的最少学校数目(子任务 A)。

更进一步,我们想要确定通过给任意一个学校发送新软件,这个软件就会分发到网络中的所有学校。为了完成这个任务,我们

可能必须扩展接收学校列表,使其加入新成员。计算最少需要增加几个扩展,使得不论我们给哪个学校发送新软件,它都会到达其余所有的学校(子任务 B)。一个扩展就是在一个学校的接收学校列表中引入一个新成员。

 

 

一个强联通分量的模板题 首先第一问的答案显然是缩点后出度为零的点的个数(起点);

第二问答案可以大胆猜测 得到其为 max(起点数加终点数)

$$ f(x) = a+b $$

假设起点数为P,终点数为Q 且P <= Q,那么我们只需要找到一个最长的起点并把各个终点向它连边即可,Q <= P 同理可得

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

int n;
const int N = 110;
const int M = 10010;
int h[N],e[M],ne[M],idx = 0;
int low[N],dfn[N],id[N],din[N],dout[N];
int timestamp = 0,scc_cnt = 0;
bool is_stk[N];
int tot = 0,stk[N];

void add(int u,int v)
{
    e[idx] = v;
    ne[idx] = h[u];
    h[u] = idx ++;
}

void tarjan(int u)
{
    low[u] = dfn[u] = ++ timestamp;
    stk[++ tot] = u;
    is_stk[u] = true;
    for(int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if(!dfn[j])
        {
            tarjan(j);
            low[u] = min(low[u],low[j]);
        }
        else if(is_stk[j]) low[u] = min(low[u],dfn[j]);
    }

    if(low[u] == dfn[u])
    {
        int y;
        scc_cnt ++;
        do
        {
            y = stk[tot --];
            is_stk[y] = false;
            id[y] = scc_cnt;

        } while (y != u);
        
    }
}

int main()
{
    memset(h,-1,sizeof h);
    scanf("%d",&n);
    for(register int i = 1; i <= n; ++ i)
    {
        int x;
        while(cin >> x,x)
        {
            add(i,x);
        }
    }
    for(register int i = 1; i <= n; ++ i)
        if(!dfn[i]) tarjan(i);
     for (int i = 1; i <= n; i ++ )
        for (int j = h[i]; ~j; j = ne[j])
        {
            int k = e[j];
            int a = id[i], b = id[k];
            if (a != b) dout[a] ++,din[b] ++;
        }
    int ans = 0,res = 0;
    for(register int i = 1; i <= scc_cnt; ++ i)
    {
        if(!din[i]) ans ++;
        if(!dout[i]) res ++;

    }
    printf("%d\n",ans);
    printf("%d\n",scc_cnt == 1 ? 0 : max(ans,res));
    return 0;
}

 

标签:学校,int,USACO5.3,stk,Schools,dfn,low,校园网,include
来源: https://www.cnblogs.com/yjyl0098/p/15375102.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有