牛客 51011 可达性统计(拓扑排序,bitset)
牛客 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)的更多相关文章
- [LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset)
[LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset) 题面 题面较长,略 分析 首先,发现火星人只有死和活两种状态,考虑2-SAT 建图 ...
- Acwing-164-可达性统计(拓扑排序, 位运算统计)
链接: https://www.acwing.com/problem/content/166/ 题意: 给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量. 思路: 先拓扑排序求 ...
- NOIP 车站分级 (luogu 1983 & codevs 3294 & vijos 1851) - 拓扑排序 - bitset
描述 一条单向的铁路线上,依次有编号为 1, 2, ..., n 的 n 个火车站.每个火车站都有一个级别,最低为 1 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车 ...
- [BZOJ4484][JSOI2015]最小表示[拓扑排序+bitset]
题意 给你一个 \(n\) 个点 \(m\) 条边的 \(\rm DAG\) ,询问最多能够删除多少条边,使得图的连通性不变 \(n\leq 3\times 10^4\ ,m\leq 10^5\) . ...
- BZOJ4484 JSOI2015最小表示(拓扑排序+bitset)
考虑在每个点的出边中删除哪些.如果其出边所指向的点中存在某点能到达另一点,那么显然指向被到达点的边是没有用的.于是拓扑排序逆序处理,按拓扑序枚举出边,bitset维护可达点集合即可. #include ...
- BZOJ5109 CodePlus 2017大吉大利,晚上吃鸡!(最短路+拓扑排序+bitset)
首先跑正反两遍dij求由起点/终点到某点的最短路条数,这样条件一就转化为f(S,A)*f(T,A)+f(S,B)*f(T,B)=f(S,T).同时建出最短路DAG,这样图中任何一条S到T的路径都是最短 ...
- CH 2101 - 可达性统计 - [BFS拓扑排序+bitset状压]
题目链接:传送门 描述 给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量.N,M≤30000. 输入格式 第一行两个整数N,M,接下来M行每行两个整数x,y,表示从x到y的一条 ...
- BZOJ 4484: [Jsoi2015]最小表示(拓扑排序+bitset)
传送门 解题思路 \(bitset\)维护连通性,给每个点开个\(bitset\),第\(i\)位为\(1\)则表示与第\(i\)位联通.算答案时显然要枚举每条边,而枚举边的顺序需要贪心,一个点先到达 ...
- 牛客 82E 无向图中的最短距离 (bitset,bfs)
有一个n个点的无向图,有m次查询,每次查询给出一些(xi,yi) 令dist(x,y)表示x和y点在图中最短距离,dist(x,x)=0,如果x,y不连通则dist(x,y) = inf 每次查询图中 ...
随机推荐
- Tomcat的基本使用及相关知识的概述(超详细版)
絮絮叨叨: 在深入了解Tomcat源码之前,本来是想亲自写一篇Tomcat的基本使用教程的,在网上兜兜转转发现了这篇博客:https://blog.csdn.net/weixin_40396459/a ...
- Linux驱动之I2C总线设备以及驱动
[ 导读] 本文通过阅读内核代码,来梳理一下I2C子系统的整体视图.在开发I2C设备驱动程序时,往往缺乏对于系统整体的认识,导致没有一个清晰的思路.所以从高层级来分析一下I2C系统的设计思路,将有助于 ...
- Go的100天之旅-01初识Go
初识Go Go简介 Go的历史 上个世纪70年代Ken Thompson和Dennis M. Ritchie合作发明了UNIX操作系统同时Dennis M. Ritchie发明了C语言. 2007年的 ...
- 作为程序员居然没用过这款神器?太out了吧。
背景 工欲善其事,必先利其器.后面我将陆陆续续推荐一些软件利器帮助大家提高效率(主要针对 Mac 电脑). 如果你在使用 Mac 电脑,并且没有如某些人那样安装并使用 Windows 系统,那么你可 ...
- nodejs之数据库连接
nodejs 对 MySQL.mongodb.redis 数据库的连接方式. MySQL: var mysql = require('mysql') var { MYSQL } = require(' ...
- linux管理防火墙
操作系统环境:CentOS Linux release 7.0.1406(Core) 64位CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙步骤. 1.关闭f ...
- Ethical Hacking - Web Penetration Testing(10)
SQL INJECTION SQLMAP Tool designed to exploit SQL injections. Works with many DB types, MySQL, MSSQL ...
- PG-跨库操作-dblink
在PostgreSQL数据库之间进行跨库操作的方式 dblink postgres_fdw 本文先说说dblink:dblink是一个支持从数据库会话中连接到其他PostgreSQL数据库的插件.在其 ...
- 做软件测试要月入20k?听听腾讯大牛怎么说
作者:兰色链接:https://www.zhihu.com/question/373819487/answer/1183309514来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- 二分图&网络流初步
链接 : 最小割&网络流应用 EK太低级了,不用. 那么请看:#6068. 「2017 山东一轮集训 Day4」棋盘,不用EK你试试? dinic模板及部分变形应用见zzz大佬的博客:网络流学 ...