AcWing 367. 学校网络 题解(tarjan dfs序时间戳+缩环成点)

11 篇文章 0 订阅
4 篇文章 0 订阅

AcWing 367. 学校网络
请添加图片描述
请添加图片描述
大佬题解原地址

#include<bits/stdc++.h>

using namespace std;

const int N = 110, M = 1e4 + 10;

int h[N], e[M], ne[M], idx;
int n, m;
bool is_stk[N];
int stk[N];
int top;
int low[N], dfn[N], timep;
int scc_cnt;
int id[N];
int din[N], dout[N];

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

void tarjan(int u){
	low[u] = dfn[u] = ++ timep;
	stk[ ++ top] = 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[top -- ];
			id[y] = scc_cnt;
			is_stk[y] = false;
		}while(y != u);
	}
}

int main()
{
	cin>>n;
	memset(h, -1, sizeof h);
	for(int i = 1; i <= n; i ++ ){
		int t;
		while(cin>>t, t) add(i, t);
	}
	
	for(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){
				din[b] ++ ;
				dout[a] ++ ;
			}
		}
	}
	//记录起点数、终点数 
	int op1 = 0, op2 = 0;
	for(int i = 1; i <= scc_cnt; i ++ ){
		if(!din[i]) op1 ++ ;
		if(!dout[i]) op2 ++ ;
	}
	
	cout<<op1<<endl;
	if(scc_cnt == 1) puts("0");
	else cout<<max(op1, op2)<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值