bzoj2208 [Jsoi2010]连通数(scc+bitset)
2208: [Jsoi2010]连通数
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 1879 Solved: 778
[Submit][Status][Discuss]
Description

Input
输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。
Output
输出一行一个整数,表示该图的连通数。
Sample Input
010
001
100
Sample Output
HINT
对于100%的数据,N不超过2000。
Source
【思路】
强连通分量+bitset传递闭包。
求出scc,缩点。对于新的DAG,如果两个scc之间相连则ans+=sccsz[i]*sccsz[j]。利用bitset与递推判断相连。
【代码】
#include<cstdio>
#include<bitset>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<iostream>
using namespace std; const int maxn = +; int pre[maxn],lowlink[maxn],sccno[maxn],sccsz[maxn],dfs_clock,scc_cnt;
vector<int> G[maxn];
stack<int> S; int dfs(int u) {
pre[u]=lowlink[u]=++dfs_clock;
S.push(u);
for(int i=;i<G[u].size();i++) {
int v=G[u][i];
if(!pre[v]) {
dfs(v);
lowlink[u]=min(lowlink[u],lowlink[v]);
}
else if(!sccno[v]) {
lowlink[u]=min(lowlink[u],pre[v]);
}
}
if(lowlink[u]==pre[u]) {
scc_cnt++;
for(;;) {
int x=S.top(); S.pop();
sccno[x]=scc_cnt;
sccsz[scc_cnt]++;
if(x==u) break;
}
}
}
void find_scc(int n) {
memset(pre,,sizeof(pre));
memset(sccsz,,sizeof(sccsz));
memset(sccno,,sizeof(sccno));
scc_cnt=dfs_clock=;
for(int i=;i<n;i++)
if(!pre[i]) dfs(i);
} bitset<maxn> f[maxn]; //使用bitset
int n,in[maxn];
char s[maxn]; vector<int> Gx[maxn];
void rebuild() {
for(int i=;i<=scc_cnt;i++) in[i]=;
for(int i=;i<n;i++) {
int u=sccno[i];
for(int j=;j<G[i].size();j++) {
int v=sccno[G[i][j]];
if(u!=v) Gx[u].push_back(v),in[v]++;
}
}
} queue<int> q;
void solve() {
for(int i=;i<=scc_cnt;i++) f[i][i]=;
for(int i=;i<=scc_cnt;i++) if(!in[i]) q.push(i);
while(!q.empty()) {
int u=q.front(); q.pop();
for(int i=;i<Gx[u].size();i++) {
int v=Gx[u][i];
f[v]|=f[u]; //传递闭包
if((--in[v])==) q.push(v);
}
}
} int main() {
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%s",s);
for(int j=;j<n;j++) {
if(s[j]-'') G[i].push_back(j);
}
}
find_scc(n);
rebuild();
solve();
int ans=;
for(int i=;i<=scc_cnt;i++)
{
for(int j=;j<=scc_cnt;j++)
if(f[i][j]) ans+=sccsz[i]*sccsz[j];
}
printf("%d\n",ans);
return ;
}
bzoj2208 [Jsoi2010]连通数(scc+bitset)的更多相关文章
- BZOJ2208: [Jsoi2010]连通数(tarjan bitset floyd)
题意 题目链接 Sol 数据水的一批,\(O(n^3)\)暴力可过 实际上只要bitset优化一下floyd复杂度就是对的了(\(O(\frac{n^3}{32})\)) 还可以缩点之后bitset维 ...
- 2018.09.11 bzoj2208: [Jsoi2010]连通数(bitset+floyd)
传送门 听说正解是缩点+dfs? 直接bitset优化floyd传递闭包就行了.(尽管时间复杂度是假的O(n3/32)" role="presentation" styl ...
- BZOJ 2208: [Jsoi2010]连通数 tarjan bitset
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- [bzoj2208][Jsoi2010]连通数_bitset_传递闭包floyd
连通数 bzoj-2208 Jsoi-2010 题目大意:给定一个n个节点的有向图,问每个节点可以到达的点的个数和. 注释:$1\le n\le 2000$. 想法:网上有好多tarjan+拓扑序dp ...
- [BZOJ2208]:[Jsoi2010]连通数(暴力 or bitset or 塔尖?)
题目传送门 题目描述 度量一个有向图连通情况的一个指标是连通数,指图中可达顶点对的个数. 在上图中,顶点1可以到达1.2.3.4.5. 顶点2可以到达2.3.4.5. 顶点3可以到达3.4.5. 顶点 ...
- BZOJ2208 [Jsoi2010]连通数[缩点/Floyd传递闭包+bitset优化]
显然并不能直接dfs,因为$m$会非常大,复杂度就是$O(mn)$: 这题有三种做法,都用到了bitset的优化.第二种算是一个意外的收获,之前没想到竟然还有这种神仙操作.. 方法一:缩点+DAG上b ...
- BZOJ2208: [Jsoi2010]连通数
tarjan缩点后拓扑排序,每一个点用一个bitset记录哪些点能到达它. PS:数据太水,暴力能过. #include<bits/stdc++.h> using namespace st ...
- [BZOJ2208][Jsoi2010]连通数 暴力枚举
Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示无边. Output 输出一行一个整数,表示该图 ...
- BZOJ2208:[JSOI2010]连通数(DFS)
Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示无边. Output 输出一行一个整数,表示该图 ...
随机推荐
- [转] restrict关键字用法
PS: 在函数中,指针参数指定了restrict,表示这个指针指向的这段区域只能通过这个指针修改 c99中新增加了一个类型定义,就是restrict. 看了下网上的相关贴子,但还是问题解决的不够.下面 ...
- Camera类
Camera类 使用 Camera 类可从连接到运行 Flash Player 的计算机的摄像头中 捕获视频. 使用 Video 类可在本地监视视频. 使用 NetConnection 和 NetS ...
- jquery/js当前URL对当前栏目高亮突出显示
html: 1 <div class="nav"> 2 <ul> 3 <li><a href="index.html" ...
- H5与Activity之间的通信(调用)
1.通过H5页面的超链接尾部信息不同进行跳转(类似于URL拦截器) 例如:控件x的href="http://www.example.com/?menu_id=1", 在代码中添加w ...
- 【转】Java学习之Iterator(迭代器)的一般用法 (转)
[转]Java学习之Iterator(迭代器)的一般用法 (转) 迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭 ...
- redisbook笔记——redis内存映射数据结构
虽然内部数据结构非常强大,但是创建一系列完整的数据结构本身也是一件相当耗费内存的工作,当一个对象包含的元素数量并不多,或者元素本身的体积并不大时,使用代价高昂的内部数据结构并不是最好的办法. 为了解决 ...
- (转)解析PHP中ob_start()函数的用法
本篇文章是对PHP中ob_start()函数的用法进行了详细的分析介绍,需要的朋友参考下 ob_start()函数用于打开缓冲区,比如header()函数之前如果就有输出,包括回车/空格/换行 ...
- Swift - 31 - 常量参数, 变量参数和inout参数
//: Playground - noun: a place where people can play import UIKit // swift中默认情况下, 传入的参数是不可以修改的, 也就是l ...
- openssl提取pfx证书密钥对
刚做银联的项目,对方给了1.pfx和1.cer两个测试文件,总结一下利用这两个文件提取出文本 银联提供两个测试证书 1.pfx 和 1.cer . 其中 pfx证书包含RSA的公钥和密钥;cer证书 ...
- Qt Painter放大时,event处理应该注意的要点
比如当你Qt中用QPainter进行window和viewport,逻辑和物理坐标分离的形式进行绘图放大的时候,你会发现鼠标的移动和放大之后的图像有点不跟手,比如你是用QTransform进行放大变换 ...