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网络请求封装