BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset

Description

Input

输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。

Output

输出一行一个整数,表示该图的连通数。

Sample Input

3
010
001
100

Sample Output

9

HINT

对于100%的数据,N不超过2000。


直接缩点+拓扑排序统计答案即可。

每步转移是O(n)的,可以用bitset优化到O(n/32)。

其实就是想练习一下手写bitset,显然没有STL的块。

总时间复杂度O(nnm/32)

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 2050
#define M 4000500
#define _min(x,y) ((x)<(y)?(x):(y))
typedef unsigned int ut;
const int M1=65535;
inline char nc() {
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
int rc() {
char s=nc();
while(s<'0'||s>'1') s=nc();
return s=='1';
}
int rd() {
int x=0; char s=nc();
while(s<'0'||s>'9') s=nc();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
return x;
}
int n,block,h[1<<16];
int g1(unsigned int x) {
return h[x>>16]+h[x&M1];
}
struct Bitset {
ut b[70];
int get_num() {
int i,re=0;
for(i=1;i<=block;i++) re+=g1(b[i]);
return re;
}
Bitset operator | (const Bitset &x) const {
Bitset re; int i;
for(i=1;i<=block;i++) re.b[i]=(b[i]|x.b[i]);
return re;
}
}f1[N],f2[N];
int head[N],to[M],nxt[M],in[N],Q[N],l,r;
int S[N],bel[N],siz[N],L[80],R[80],pos1[N],pos2[N],dfn[N],low[N],tot,scc,top,ins[N],xx[M],yy[M],qwq,cnt;
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void dfs(int x) {
int i;
dfn[x]=low[x]=++tot; S[++top]=x; ins[x]=1;
for(i=head[x];i;i=nxt[i]) {
if(!dfn[to[i]]) {
dfs(to[i]);
low[x]=_min(low[x],low[to[i]]);
}else if(ins[to[i]]) {
low[x]=_min(low[x],dfn[to[i]]);
}
}
if(dfn[x]==low[x]) {
int t=S[top--]; ins[t]=0;
bel[t]=++scc; f2[scc]=f1[t];
siz[scc]=1;
while(t!=x) {
t=S[top--]; ins[t]=0;
bel[t]=scc; f2[scc]=f2[scc]|f1[t];
siz[scc]++;
}
}
}
int main() {
n=rd();
register int i,j;
int x;
for(i=1;i<=M1;i++) h[i]=h[i>>1]+(i&1);
block=n/32;
for(i=1;i<=block;i++) {
L[i]=R[i-1]+1; R[i]=i*32;
for(j=L[i];j<=R[i];j++) {
pos1[j]=i; pos2[j]=j-L[i];
}
}
if(R[block]!=n) {
L[block+1]=R[block]+1; R[++block]=n;
for(i=L[block];i<=n;i++) pos1[i]=block,pos2[i]=i-L[block];
}
for(i=1;i<=n;i++) {
for(j=1;j<=n;j++) {
x=rc();
if(x) f1[i].b[pos1[j]]|=(1<<pos2[j]),add(i,j),xx[++qwq]=j,yy[qwq]=i;
}
f1[i].b[pos1[i]]|=(1<<pos2[i]);
}
for(i=1;i<=n;i++) {
if(!dfn[i]) dfs(i);
}
memset(head,0,sizeof(head)); cnt=0;
for(i=1;i<=qwq;i++) {
if(bel[xx[i]]!=bel[yy[i]]) {
add(bel[xx[i]],bel[yy[i]]); in[bel[yy[i]]]++;
}
}
for(i=1;i<=scc;i++) {
if(!in[i]) Q[r++]=i;
}
int ans=0;
while(l<r) {
x=Q[l++]; ans+=siz[x]*f2[x].get_num();
for(i=head[x];i;i=nxt[i]) {
in[to[i]]--;
f2[to[i]]=f2[to[i]]|f2[x];
if(in[to[i]]==0) Q[r++]=to[i];
}
}
printf("%d\n",ans);
}

BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset的更多相关文章

  1. BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP

    BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP Description In an effort to better manage t ...

  2. poj 2762(强连通分量+拓扑排序)

    题目链接:http://poj.org/problem?id=2762 题意:给出一个有向图,判断任意的两个顶点(u,v)能否从u到达v,或v到达u,即单连通,输出Yes或No. 分析:对于同一个强连 ...

  3. BZOJ1924:[SDOI2010]所驼门王的宝藏(强连通分量,拓扑排序)

    Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...

  4. 2019ICPC(银川) - Delivery Route(强连通分量 + 拓扑排序 + dijkstra)

    Delivery Route 题目:有n个派送点,x条双向边,y条单向边,出发点是s,双向边的权值均为正,单向边的权值可以为负数,对于单向边给出了一个限制:如果u->v成立,则v->u一定 ...

  5. CDOJ 图论专题 A.不是图论 强连通分量+拓扑排序 经典

    题目链接  在其中纠错第一次wa代码 #include <cstdio> #include <cstring> #include <cstdlib> #includ ...

  6. POJ 2762 Going from u to v or from v to u?(强连通分量+拓扑排序)

    职务地址:id=2762">POJ 2762 先缩小点.进而推断网络拓扑结构是否每个号码1(排序我是想不出来这点的. .. ).由于假如有一层为2的话,那么从此之后这两个岔路的点就不可 ...

  7. BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量

    BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人 ...

  8. BZOJ_2140_稳定婚姻_强连通分量

    BZOJ_2140_稳定婚姻_强连通分量 Description 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚 姻问题的专家认为,是与简化离 ...

  9. BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP

    BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP Description 受到秘鲁的马丘比丘的新式水上乐园的启发,Farmer John决定也为奶牛们建 一个水上乐园. ...

随机推荐

  1. Windows10下Apache2.4配置Django

    开发环境 Windows 10 x64 Apache 2.4 x64 Python 2.7.11 x64 Django 1.9.6+ 下载和安装mod_wsgi 到 http://download.c ...

  2. vue-router 的URL路径中#的意义

    传送门 https://router.vuejs.org/zh-c... Router 构造配置 routes 类型: Array<RouteConfig> RouteConfig 的类型 ...

  3. AngularJS的ng-repeat显示属性名和属性值

    代码下载:https://files.cnblogs.com/files/xiandedanteng/AngularJSAuthorRepeat.rar 代码: <!DOCTYPE HTML P ...

  4. PS 如何使用钢笔工具

    1.钢笔工具属于矢量绘图工具,其优点是可以勾画平滑的曲线,在缩放或者变形之后仍能保持平滑效果. 2.钢笔工具画出来的矢量图形称为路径,路径是矢量的路径允许是不封闭的开放状,如果把起点与终点重合绘制就可 ...

  5. 关于JavaScript禁止点击事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. hdu 4432 数学杂题

    http://acm.hdu.edu.cn/showproblem.php?pid=4432 6分钟写的代码,一上午去调试,, 哎,一则题目没看懂就去写了,二则,哎,,恶心了.在坚持几天然后ACM退役 ...

  7. 《UNIX-Shell编程24学时教程》读书笔记Chap3,4 文件,目录操作

    Chap3 文件操作   P28 在这章中,要着重记住一些常用的选项,要有使用正则表达式的思维,能更快达到目的.----@im天行 3.1 列文件名 .profile  sh的初始化脚本: .kshr ...

  8. Google的分布式计算模型Map Reduce map函数将输入分割成key/value对

    http://www.nowamagic.net/librarys/veda/detail/1768 上一篇 大规模分布式数据处理平台Hadoop的介绍 中提到了Google的分布式计算模型Map R ...

  9. 关于Swiper(概念)

    Swiper 是一款免费以及轻量级的移动设备触控滑块的js框架,使用硬件加速过渡(如果该设备支持的话). 主要使用于移动端的网站.移动web apps,native apps和hybrid apps. ...

  10. Linux 磁盘空间查询&&解决Linux 中“磁盘空间不足”的问题

    一.linux 查看目录的剩余空间大小 两个命令df .du结合比较直观 df -h 查看整台服务器的硬盘使用情况 du -lh --max-depth=1 : 查看当前目录下一级子文件和子目录占用的 ...