牛客 51011 可达性统计(拓扑排序,bitset)

题意:

给一个 n个点,m条边的有向无环图,分别统计每个点出发能够到达的点的数量(包括自身) \(n,m\le30000\).

样例:

10 10
3 8
2 3
2 5
5 9
5 9
2 3
3 9
4 8
2 10
4 9

题解:

想要统计每个点能够出发到达的点数量,如果一个一个点来搜索计算的话,那么复杂度将会变成 \(O(n^2)\),所以我们要换个角度思考,在访问每一个点的时候,考虑由哪个点可以到达它,所以我们可以反向建边,按照图拓扑排序的顺序进行访问,将自身的贡献传递给自己的临点。

​ 但是计算贡献的时候,要考虑重复的计算,如下图(已经是反向建边了),D点访问过后,A和C点的贡献都为2,如果再一次 访问完A和C后,B的贡献就会变成5,显然的多计算了一次D的贡献。

​ 在这里我们可以引入二进制位来避免这种情况发生,也就是用一个数字的二进制数来表示一个点的贡献,这个二进制数第i位为 \(i\),则代表这个点可以到达 \(i\),设上图的A,B,C,D点分别为点1,2,3,4.那么起始的点1,2,3,4的贡献可以记录为 2,4,8,16.其实是他们的二进制位的第一位,第二位,第三位,第四位设位1了,那么点A的贡献将为 \(val_A | val_D\)=2|16 =18,C的贡献为 \(valD|valC\)=16|8 =24.这样点B的贡献将为\(valA|valB|valC\)=18 | 24 | 4=30.这代表着B点可以到达第一个点,第二个,第三个点,第四个点。由于或运算的关系,D的贡献不会重复计算。不过这里还有一个问题是由于数据规模的原因我们不能直接用数字来表示二进制位的贡献,因此我们要引入bitset。

bitset

bitset是C++提供的一个模板类,原型为 template<size_t N>class bitset。参数是bitset的二进制位的个数。

bitset<6>B;//这里我们定义了一个长度为40的bitset,它的每一位都是bool类型,占内存1bit
B[2]=1;//每一个位置都可以通过下标来访问以及进行修改。
bitset<6>C(string("101"));//我们还可以用一个只包含0和1字符的string类来初始话这个bitset,
//这里bitset的值依次为000101.是string的长度超过bitset的长度,字符串后面的字符会被舍弃掉。
C.count();//输出C种为1的bool元素的个数。这里结果为2.
C.reset();//将C的所有的位数全部置为1.
B = B|C;//同时支持 或,与,异或 这种位运算。要保证他们的长度要相同。

​ 有了bitset的这些操作后,思路就很明显了,按照拓扑排序的顺序访问,每一次用bitset来传递贡献,最后输出每个bitset种为1的bool元素的个数。

struct P{int x;int y;P(){}P(int _x,int _y):x(_x),y(_y){}};
vector<int>ege[maxn];
bitset<maxn>cnt[maxn];
set<P>S;
int in[maxn]={0};
bool operator<(const P a,const P b){//
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
void solve(){
int n,m;scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
int x,y;scanf("%d %d",&x,&y);
if(S.count(P(x,y)))continue;//将重复元素筛掉。
S.insert(P(x,y));
++in[x];
ege[y].push_back(x);
}
for(int i=1;i<=n;i++)cnt[i][i]=1;//将第i个bitset的第i位初始化1.
queue<int>q;
for(int i=1;i<=n;i++){
if(in[i]==0)q.push(i);
}
while(!q.empty()){
int u = q.front();
q.pop();
for(int v:ege[u]){
--in[v];
cnt[v] = cnt[v]|cnt[u];//用或运算将u的贡献传递给v。
if(in[v]==0)q.push(v);
}
}
for(int i=1;i<=n;i++)printf("%d\n",cnt[i].count());
}

牛客 51011 可达性统计(拓扑排序,bitset)的更多相关文章

  1. [LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset)

    [LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset) 题面 题面较长,略 分析 首先,发现火星人只有死和活两种状态,考虑2-SAT 建图 ...

  2. Acwing-164-可达性统计(拓扑排序, 位运算统计)

    链接: https://www.acwing.com/problem/content/166/ 题意: 给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量. 思路: 先拓扑排序求 ...

  3. NOIP 车站分级 (luogu 1983 & codevs 3294 & vijos 1851) - 拓扑排序 - bitset

    描述 一条单向的铁路线上,依次有编号为 1, 2, ..., n 的 n 个火车站.每个火车站都有一个级别,最低为 1 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车 ...

  4. [BZOJ4484][JSOI2015]最小表示[拓扑排序+bitset]

    题意 给你一个 \(n\) 个点 \(m\) 条边的 \(\rm DAG\) ,询问最多能够删除多少条边,使得图的连通性不变 \(n\leq 3\times 10^4\ ,m\leq 10^5\) . ...

  5. BZOJ4484 JSOI2015最小表示(拓扑排序+bitset)

    考虑在每个点的出边中删除哪些.如果其出边所指向的点中存在某点能到达另一点,那么显然指向被到达点的边是没有用的.于是拓扑排序逆序处理,按拓扑序枚举出边,bitset维护可达点集合即可. #include ...

  6. BZOJ5109 CodePlus 2017大吉大利,晚上吃鸡!(最短路+拓扑排序+bitset)

    首先跑正反两遍dij求由起点/终点到某点的最短路条数,这样条件一就转化为f(S,A)*f(T,A)+f(S,B)*f(T,B)=f(S,T).同时建出最短路DAG,这样图中任何一条S到T的路径都是最短 ...

  7. CH 2101 - 可达性统计 - [BFS拓扑排序+bitset状压]

    题目链接:传送门 描述 给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量.N,M≤30000. 输入格式 第一行两个整数N,M,接下来M行每行两个整数x,y,表示从x到y的一条 ...

  8. BZOJ 4484: [Jsoi2015]最小表示(拓扑排序+bitset)

    传送门 解题思路 \(bitset\)维护连通性,给每个点开个\(bitset\),第\(i\)位为\(1\)则表示与第\(i\)位联通.算答案时显然要枚举每条边,而枚举边的顺序需要贪心,一个点先到达 ...

  9. 牛客 82E 无向图中的最短距离 (bitset,bfs)

    有一个n个点的无向图,有m次查询,每次查询给出一些(xi,yi) 令dist(x,y)表示x和y点在图中最短距离,dist(x,x)=0,如果x,y不连通则dist(x,y) = inf 每次查询图中 ...

随机推荐

  1. 使用truncate ,截断有外键约束的父表

    此时有两种方法,解决1.删除外键约束,删除该表,在重建外键约束--查询外键约束select TABLE_NAME,CONSTRAINT_NAME,CONSTRAINT_TYPE,R_CONSTRAIN ...

  2. Redis 6.0 新特性 ACL 介绍

    Redis 6.0 新特性 ACL 介绍 Intro 在 Redis 6.0 中引入了 ACL(Access Control List) 的支持,在此前的版本中 Redis 中是没有用户的概念的,其实 ...

  3. Disease Manangement 疾病管理

    题目描述 Alas! \(A\) set of \(D (1 <= D <= 15)\) diseases (numbered \(1..D\)) is rshning through t ...

  4. xenomai内核解析--双核系统调用(三)--如何为xenomai添加一个系统调用

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正. @ 目录 一.添加系统调用 二.Cobalt库添加接口 三.应用使用 一.添加系统调用 下面给xenomai添加一个系统调用g ...

  5. Docker 基础知识 - 使用绑定挂载(bind mounts)管理应用程序数据

    绑定挂载(bind mounts)在 Docker 的早期就已经出现了.与卷相比,绑定挂载的功能有限.当您使用绑定挂载时,主机上的文件或目录将挂载到容器中.文件或目录由其在主机上的完整或相对路径引用. ...

  6. 题解 洛谷 P4336 【[SHOI2016]黑暗前的幻想乡】

    生成树计数的问题用矩阵树定理解决. 考虑如何解决去重的问题,也就是如何保证每个公司都修建一条道路. 用容斥来解决,为方便起见,我处理时先将\(n\)减了1. 设\(f(n)\)为用\(n\)个公司,且 ...

  7. vue history路由模式 Nginx 生产实践

    nginx(带二级目录的配置) location ~* /A {    alias  /opt/nginx-1.4.7/html/ued/A;     try_files $uri $uri /A/s ...

  8. Java基础-语法基础

    一.Java中的关键字和保留字 关键字:某种语言赋予了特殊含义的单词 保留字:没有赋予特殊含义,但是准备日后要使用的单词 二.Java中的标识符 其实就是在从程序中自定义的名词.比如类名.变量名,函数 ...

  9. CSS 技巧一则 -- 不定宽溢出文本适配滚动

    在日常布局当中,肯定经常会遇到文本内容超过容器的情况.非常常见的一种解决方案是超出省略. 但是,有的时候,由于场景的限制,可能会出现在一些无法使用超出打点省略的方法的场景,譬如在导航栏中: 这种情况下 ...

  10. REST是什么?RESTFul又是什么?这二者的关系是怎样的?

    REST(一种软件架构风格) 全称:Representational State Transfer 含义:(表述性 状态 转移) 是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可 ...