P2812 校园网络

Posted wondering-world

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2812 校园网络相关的知识,希望对你有一定的参考价值。

https://www.luogu.com.cn/problem/P2812  传送门

 

首先考虑问题一


不难想到,如果有一个学校作为终端机,那么跟其处于同一个强联通中的所有学校就可以不用作为终端机了。 那么,问题一也就迎刃而解了:找到所有入度为0的缩点。因为这个学校(强联通中至少有一个学校)必须作为终端机,毕竟它收不到别的学校传来的,只能自给自足。

然后考虑问题二

“任意一个学校都能作为母鸡”?试想一下,任意选取一个学校作为终端,要使得其余所有学校都能收到,只能是全图联通。因此,找到出度为0的缩点的个数就ok了。(即从出度为0的点连向入度为0 的点)

不废话,上代码。细节已标好

 

#include <bits/stdc++.h>
using namespace std;
#define N 5000010
#define orz 0

inline int read(){
    int x = 0, s = 1;
    char c = getchar();
    while(!isdigit(c)){
        if(c == -)s = -1;
        c = getchar();
    }
    while(isdigit(c)){
        x = (x << 1) + (x << 3) + (c ^ 0);
        c = getchar();
    }
    return x * s;
} 

struct node{
    int u, v;
    int next;
} t[N];
int f[N];//日常邻接表 

int stac[N], top = 0;
int dfn[N], scc[N], low[N];
bool vis[N];
//tarjan 板子,不多说 
int in[N], out[N];//入度出度 
int ans1 = 0, ans2 = 0;

int bian = 0;
inline void add(int u, int v){
    t[++bian].v = v;
    t[bian].u= u;
    t[bian].next = f[u];
    f[u] = bian;
    return ;
}

int cac = 0, cnt = 0;
void tarjan(int now){//有向图强联通板子 
    dfn[now] = low[now] = ++ cac;
    stac[++top] = now;
    vis[now] = 1;
    for(int i = f[now]; i;i = t[i].next){
        int v = t[i].v;
        if(!dfn[v]){
            tarjan(v);
            low[now] = min(low[now], low[v]);
        }
        else if(vis[v])low[now] = min(low[now], dfn[v]);
    }
    if(dfn[now] == low[now]){
        int cur; 
        cnt++;
        do{
            cur = stac[top--];
            vis[cur] = 0;
            scc[cur] = cnt;
        }while(cur != now);
    }
    return ;
}

int main(){
    int n = read();
    for(int i = 1;i <= n; i++){
        int x = read();
        while(x){
            add(i, x);
            x = read();
        }
    }
    for(int i = 1;i <= n;i++)
        if(!dfn[i]) tarjan(i);//注意防止有的点漏掉 
    for(int i = 1;i <= bian; i++){ //统计所有的边 
        int u = t[i].u, v = t[i].v;
        if(scc[u] != scc[v]){//如果起点和终点不在同一个缩点  (即在两个缩点的交界处的边) 
            out[scc[u]]++;
            in[scc[v]]++;
        }

    }
    for(int i = 1;i <= cnt; i++){
        if(!in[i])ans1++;
        if(!out[i])ans2++;//统计 
    }
    printf("%d
%d", ans1, ans2);
    return orz;         //%一下CCF求AC 
}

 

以上是关于P2812 校园网络的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

201555332盛照宗—网络对抗实验1—逆向与bof基础

20155201 李卓雯 《网络对抗技术》实验一 逆向及Bof基础