zoukankan      html  css  js  c++  java
  • 可达性统计

    AcWing

    题意:给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量.((N,M<=30000))

    分析:设(f(x))表示x能够到达的点的集合,先求出该图的拓扑序,因为对于任意一条有向边(x,y),先要求出(f(y))才能求出(f(x)).我们用(bitset)开f数组,把f[i]看作一个N位的二进制数,某一位为1则代表可以到达,对i的所有儿子做“按位或”运算即可把i的儿子能够到达的点统计到i上.

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<bitset>
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=30005;
    int cnt,a[N];
    int tot,head[N],nxt[N],to[N],deg[N];
    bitset<N> f[N];
    vector<int> Q[N];
    queue<int>q;
    inline void add(int a,int b){
    	nxt[++tot]=head[a];head[a]=tot;to[tot]=b;
    	++deg[b];
    }
    inline void topsort(int n){
    	for(int i=1;i<=n;++i)if(!deg[i])q.push(i);
    	while(q.size()){
    		int u=q.front();q.pop();
    		a[++cnt]=u;
    		for(int i=head[u];i;i=nxt[i]){
    			int v=to[i];f[u][v]=1;
    			--deg[v];if(!deg[v])q.push(v);
    		}
    	}
    }
    int main(){
    	int n=read(),m=read();
    	for(int i=1;i<=m;++i){
    		int x=read(),y=read();
    		add(x,y);Q[x].push_back(y);
    	}
    	topsort(n);
    	for(int i=cnt;i>=1;--i){
    		for(int j=0;j<Q[a[i]].size();++j){
    			f[a[i]]|=f[Q[a[i]][j]];
    		}
    	}
    	for(int i=1;i<=n;++i)printf("%d
    ",f[i].count()+1);
        return 0;
    }
    
    
  • 相关阅读:
    MySQL Backup mysqldump 常用选项与主要用法--转发
    openssl 之RSA加密
    Windows 之Dll/lib导出
    缓存雪崩、击穿、穿透
    时间复杂度
    分布式事务
    mysql主从复制与读写分离
    什么是消息队列?
    微服务架构演化
    高并发问题常规思路
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11248198.html
Copyright © 2011-2022 走看看