牛客 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 每次查询图中 ...
随机推荐
- Alexnet网络结构
最近试一下kaggle的文字检测的题目,目前方向有两个ssd和cptn.直接看看不太懂,看到Alexnet是基础,今天手写一下网络,记录一下啊. 先理解下Alexnet中使用的原件和作用: 激活函数使 ...
- 没内鬼,来点干货!volatile和synchronized
题外话 这篇笔记是我<没内鬼>系列第二篇,其实我计划是把设计模式和多线程并发分为两个系列,统一叫<一起学系列>来系统的介绍 相关的知识,但是想到这篇笔记去年就写成了,一直不发心 ...
- easyUI时间控件
##=============================JSP======================================<div class="labelw l ...
- MSSQL系列 (二):表相关操作、列操作、(唯一、主键、默认、检查、外键、非空)约束、临时表
1.创建表 --创建学生班级表 create table StuClass ( ClassId int primary key, --班级ID 主键约束 ClassName nvarchar(30) ...
- 当小程序遇见物联网IoT,几行代码搞定智能插座控制
在 5G 热潮的推动下,与其紧密结合的物联网(IoT)正日益成为个人和企业工作生活中的重要组成部分,它为企业和个人带来了操作流程的改进和更好的生活体验,随着人工智能(AI)技术的日趋成熟,IoT 与 ...
- vue------反响代理
//测试项目 https://i.cnblogs.com/Files.aspx
- @Autowired还可以注入List和Map
@LoadBalanced@Autowired(required = false)private List<RestTemplate> restTemplates = Collection ...
- 面试题四十二:连续子数组的最大和,要求时间复杂度为 n
方法一:举例分析数组的规律,累加数组逐步保存最大值:累加中和<0,则遗弃前面的累加和:重新开始: int FindMaxArray(int [] A) { if(A= ...
- SpringBoot + Spring Cloud Eureka 服务注册与发现
什么是Spring Cloud Eureka Eureka是Netflix公司开发的开源服务注册发现组件,服务发现可以说是微服务开发的核心功能了,微服务部署后一定要有服务注册和发现的能力,Eureka ...
- flask中的endpoint是什么
app.view_functions 是一个字典,里面是存储的是 endpoint 与 视图函数的键值对,如果没指名函数视图的endpoint,默认是函数名,而 url_map 是一个列表,里面是ur ...