AcWing 164. 可达性统计 题解(拓扑排序)

该博客介绍了如何利用bitset进行状态压缩,并结合拓扑排序解决可达性统计的问题。通过建立邻接表,进行拓扑排序,然后逆序执行动态规划,进行位运算来确定每个节点能到达的其他节点数量。这种方法在处理大规模数据时具有较高的效率。
摘要由CSDN通过智能技术生成

AcWing 164. 可达性统计
新掌握一个容器bitsetS,这个二进制数S的长度为N,可以储存N位二进制数。可以说是一个多位二进制数,每八位占用一个字节,因为支持基本的位运算,所以可用于状态压缩,n位bitset执行一次位运算的时间复杂度可视为n/32.
用二进制的1表示可达到的点,先进行拓扑排序,之后按拓扑排序的逆序进行dp,进行或运算,f[i]储存的是点i能到达那些点,每个1都表示一个点

#include<bits/stdc++.h>

using namespace std;

const int N = 31000, M = 62000;

int h[N], e[M], ne[M], idx;
bitset<N>f[N];  //记录N个二进制数
int n, m;
int din[N];
int q[N];

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

void topsort(){
	int hh = 0, tt = -1;
	for(int i = 1; i <= n; i ++ ){
		if(!din[i]){
			q[ ++ tt] = i;
		}
	}
	
	while(hh <= tt){
		int t = q[hh ++ ];
		for(int i = h[t]; ~i; i = ne[i]){
			int j = e[i];
			if( -- din[j] == 0) q[ ++ tt] = j;
		}
	}
}

int main()
{
	cin>>n>>m;
	memset(h, -1, sizeof h);
	while(m -- ){
		int a, b;
		cin>>a>>b;
		add(a, b);
		din[b] ++ ;
	}
	
	topsort();
	
	for(int i = n - 1; i >= 0; i -- ){
		int j = q[i];
		f[j][j] = 1;
		for(int k = h[j]; ~k; k = ne[k]){
			int u = e[k];
			f[j] |= f[u];			
		}
	}
	
	for(int i = 1; i <= n; i ++ ) cout<<f[i].count()<<endl;
	
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值