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;
    }
    
    
  • 相关阅读:
    对Item中定时器的理解
    ClassLoader类加载机制&&JVM内存管理
    基于Quartz实现简单的定时发送邮件
    基于NIO的Socket通信
    1、svn架设、基本命令
    sysbench基准测试(2)——oltp.lua测试
    sysbench基准测试工具使用
    1、linux软件包管理
    7、数据结构五:sorted sets
    6、数据类型四:sets
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11248198.html
Copyright © 2011-2022 走看看