bzoj 2208: [Jsoi2010]连通数 拓扑排序+强连通分量+bitset
来源:互联网 发布:赣州四中官网网络阅卷 编辑:程序博客网 时间:2024/05/17 02:03
题意
给出一个有向图,求有多少个点对(i,j)满足i可以到达j(i可以等于j)
分析
这题据说暴力也能卡过去,毕竟20s的时限我才跑了1s+,但打暴力的话就没意思了,所以就果断码了一波正解。
这题一开始也有一点大概的思路也就是用bitset之类的状态压缩来搞一搞,但是没想到用tarjan来缩点。
那么正解其实就是先用tarjan来缩一下点,那么每个强连通分量对ans的贡献就是size*size,然后拓扑排序一下,再用bitset来记录每个点能到达那些点就好了。
总结
以后碰到求有向图无向图求连通数的时候要记得用tarjan缩点。
第一次用bitset
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<bitset>#include<stack>#define N 2005using namespace std;bitset <N> vis[N];stack <int> q;int low[N],dfn[N],bel[N],size[N],map[N][N],map1[N][N],n,tot,sum,ans,du[N],f[N];char str[N];void tarjan(int x){ dfn[x]=++tot; low[x]=tot; q.push(x); f[x]=1; for (int i=1;i<=n;i++) if (map[x][i]&&!dfn[i]) { tarjan(i); low[x]=min(low[x],low[i]); } else if (map[x][i]&&f[i]) low[x]=min(low[x],low[i]); if (low[x]==dfn[x]) { sum++; while (1) { int j=q.top(); q.pop(); f[j]=0; bel[j]=sum; size[sum]++; vis[sum][j]=true; if (j==x) break; } ans+=size[sum]*size[sum]; }}stack <int> q1;void topsort(){ while (!q.empty()) q.pop(); for (int i=1;i<=sum;i++) if (!du[i]) { q.push(i); q1.push(i); } while (!q1.empty()) { int x=q1.top(); q1.pop(); for (int i=1;i<=sum;i++) if (map1[x][i]) { du[i]--; if (!du[i]) { q.push(i); q1.push(i); } } }}int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%s",str); for (int j=0;j<n;j++) if (str[j]=='1') map[i][j+1]=1; } for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (map[i][j]&&!map1[bel[i]][bel[j]]&&bel[i]!=bel[j]) { map1[bel[i]][bel[j]]=1; du[bel[j]]++; } topsort(); while (!q.empty()) { int x=q.top(); q.pop(); bitset <N> t; for (int i=1;i<=sum;i++) if (map1[x][i]) t|=vis[i]; ans+=t.count()*size[x]; vis[x]|=t; } printf("%d",ans); return 0;}
0 0
- bzoj 2208: [Jsoi2010]连通数 拓扑排序+强连通分量+bitset
- bzoj 2208 [Jsoi2010]连通数 bitset
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
- bzoj 2208: [Jsoi2010]连通数 (dfs|tarjan+bitset+拓扑序)
- [tarjan+bitset]BZOJ 2208——[Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数
- 【BZOJ 2208】 [Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数
- BZOJ 2208: [Jsoi2010]连通数
- BZOJ 2208 [Jsoi2010]连通数
- BZOJ 2208: [Jsoi2010]连通数
- BZOJ 2208 [Jsoi2010]连通数
- 2208: [Jsoi2010]连通数(Trajan+bitset)
- bzoj2208 [Jsoi2010]连通数(tarjan缩点+拓扑排序+bitset传递闭包)
- 【图论】强连通分量和拓扑排序
- 【BZOJ 1093】【ZJOI 2007】【最大半连通子图】【tarjan强连通分量】【拓扑排序dp】
- BZOJ 2208 [Jsoi2010]连通数 tarjan缩点+bitset优化DP
- Android四大基本组件介绍与生命周期
- Atitit 软件项目非法模块与功能的管理与 监狱管理的对比 原理与概论attilax总结
- 算法Week08.04 - LeetCode 46. Permutations
- 关于客户端断开连接后服务器抛出异常Connection reset
- 356_实现头布局加ViewPager
- bzoj 2208: [Jsoi2010]连通数 拓扑排序+强连通分量+bitset
- 第73篇 webrtc一对一(二)及php及JS
- ubuntu下SVN服务的安装与配置
- 错误笔记(保持更新)
- 锁屏和亮屏控制
- ApplicationContext
- 357_视频音量调控View
- <第五章>Node 学习笔记 |>HTTP知识填充<|
- 视觉显著性检测