zoukankan      html  css  js  c++  java
  • AcWing 164 可达性统计 (拓扑排序 + bitset)

    题目链接:https://www.acwing.com/problem/content/description/166/

    拓扑排序:
    对于图中每条边((x,y)), 如果在序列(A)中,(x) 始终出现在 (y) 的前面,则称序列 (A) 为该图的拓扑序

    (bfs) 求解拓扑序,首先让所有入度为 (0) 的点入队,然后每次取出队首节点,加入拓扑序,
    遍历该节点的出边,出边节点入读减一,如果减一后入度变为 (0),则将此出边节点入队

    bitset:
    需要头文件:
    #include<bitset>
    支持集合操作,复杂度为 (frac{理论复杂度}{32})
    初始化:

    bit.size()       返回大小(位数)
    bit.count()     返回1的个数
    bit.any()       返回是否有1
    bit.none()      返回是否没有1
    bit.set()       全都变成1
    bit.set(p)      将第p + 1位变成1(bitset是从第0位开始的!) 
    bit.set(p, x)   将第p + 1位变成x
    bit.reset()     全都变成0
    bit.reset(p)    将第p + 1位变成0
    bit.flip()      全都取反
    bit.flip(p)     将第p + 1位取反
    bit.to_ulong()  返回它转换为unsigned long的结果,如果超出范围则报错
    bit.to_ullong() 返回它转换为unsigned long long的结果,如果超出范围则报错
    bit.to_string() 返回它转换为string的结果
    
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<bitset>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 30010;
    
    int n, m, tot;
    
    bitset<maxn> f[maxn];
    
    queue<int> q;
    
    int h[maxn], d[maxn], tp[maxn], cnt = 0;
    
    struct E{
    	int to, next;
    }e[maxn<<1];
    
    void add(int u, int v){
    	e[++cnt].next = h[u];
    	e[cnt].to = v;
    	h[u] = cnt;
    } 
    
    void topsort(){
    	for(int i=1;i<=n;++i){
    		if(!d[i]) q.push(i);
    	}
    	
    	while(!q.empty()){
    		int u = q.front(); q.pop();
    		tp[++tot] = u;
    		for(int i=h[u];i!=-1;i=e[i].next){
    			int v = e[i].to;
    			if(--d[v] == 0) q.push(v);
    		}
    	}
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	memset(h, -1, sizeof(h));
    	n = read() ,m = read(); tot = 0;
    	
    	int u, v;
    	for(int i=1;i<=m;++i){
    		u = read(), v = read();
    		++d[v];
    		add(u, v); 
    	} 
    	
    	topsort();
    	
    	for(int i=n;i>=1;--i){
    		u = tp[i];
    		f[u][u] = 1;
    		for(int j=h[u];j!=-1;j=e[j].next){
    			v = e[j].to;
    			f[u] |= f[v];
    		}
    	}
    	
    	for(int i=1;i<=n;++i) cout << f[i].count() << endl;
    	
    	return 0;
    }
    
  • 相关阅读:
    SAXParseException;前言中不允许有内容的错误
    FATAL Alert:BAD_CERTIFICATE
    DB2的递归
    在Unity中针对屏幕自适应,我们该如何做呢?
    原码与反码的区别?
    在Unity 3D中加入Image图片
    你的外接键盘的小键盘在Num Lock键亮着的,但是数字按了不能用,解决办法在这里
    唯美英文(一)
    如何使用gcc编译器
    C++中const的用法
  • 原文地址:https://www.cnblogs.com/tuchen/p/13945894.html
Copyright © 2011-2022 走看看