给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量. 输入格式 第一行两个整数N,M,接下来M行每行两个整数x,y,表示从x到y的一条有向边. 输出格式 输出共N行,表示每个点能够到达的点的数量. 数据范围 1≤N,M≤300001≤N,M≤30000 输入样例: 10 10 3 8 2 3 2 5 5 9 5 9 2 3 3 9 4 8 2 10 4 9 输出样例: 1 6 3 3 2 1 1 1 1 1 算法:拓扑排序 + 状态压缩算法 题解:首先求出该有向无环图的拓扑…
给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量. 输入格式 第一行两个整数N,M,接下来M行每行两个整数x,y,表示从x到y的一条有向边. 输出格式 输出共N行,表示每个点能够到达的点的数量. 数据范围 1≤N,M≤30000 显然可以用拓扑排序+状态压缩来做, 用一个n位的二进制数存每一个f[x], 其中第i位是1表示x能到i,0则不能到i, 这样就相当于存在x 到 y的一条边,f[x] |= f[y], 再预处理处拓扑序, 反向枚举, 最后判断每个f[i]中的个数,…
链接: https://www.acwing.com/problem/content/166/ 题意: 给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量. 思路: 先拓扑排序求出顺序, 再通过bitset利用位运算,记录并集, 可以解决重复计算的问题. 代码: #include <bits/stdc++.h> using namespace std; const int MAXN = 3e4+10; vector<int> G[MAXN]; vector&l…
Analysis 这道题我一开始想到的是传递闭包,但是时间复杂度是n³,也开不下30000*30000的数组,所以我想到了拓扑+状态压缩(bitset),从后往前找,把能到达的点能到哪里用位运算赋到上一个中,最后调用.count()输出就好了. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<…
拓扑排序+状态压缩 考虑每一个点能够到达的所有点都是与该店相邻的点的后继节点,可知: 令f[u]表示u点可到达的节点个数,f[u]={u}与f[v](u, v)的并集 于是可以利用状态压缩,能够到达的节点用1表示,这样更新f的时候直接求并集即可 #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; inline int lowbit(int x){ return x…
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-chil…
[题目描述] 给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量.N,M≤30000. [题目链接] 2101 可达性统计 [算法] 拓扑排序之后逆序计算(感觉dfs更好写而且应该更快一点),bitset状态压缩模拟集合的并操作. [代码] #include <bits/stdc++.h> using namespace std; int n,m,tot,cnt; struct edge{ int to,next; }e[30010]; int head[30010],t…
牛客 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)\),所以我们要换个角度思考,在访问每一个点的时候,考虑由哪个点可以到达它,所以我们可以反向建边,按照图…
做多校的时候遇见一个求拓扑排序数量的题,就顺便来写了一下. 题意: 你有个朋友是KOF的狂热粉丝,他有一个对其中英雄的强弱比较,让你根据这些比较关系来给这些英雄排名.问一共有多少种排名方式. 思路: 用dp[S]记录当前状态的数量. S表示拓扑排序中当前阶段已经被排序的点的集合.然后就可以枚举当前排序的点,转移的条件是这个点的所有前驱都被排序,而且这个点没被排序.然后转移就好了,最终状态就是所有点都完成排序. 代码: #include <iostream> #include <cstdi…
洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的输出状态只有\(0/1\),于是每个点的总状态也非常有限,可以根据权值为\(1\)的儿子数量\(0-3\)分为四种,记为该点的点权. 我们都会模拟暴力过程--先改叶子节点(先默认为\(0\)改为\(1\)),如果它的父亲此时权值为\(1\)的儿子数量从原来小于\(0\)的变成大于\(0\)的,那么父…