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. 渗透测试思路 | Linux下自动化搭建FakeAP,劫持用户在Portal认证下的所有流量

    如何在linux下搭建一个fakeap,使得portal认证下的用户无法发现连接你的假AP,并且能够正常上网.先说一下portal认证.无线WIFI认证方式主要有wpa2 和 open两种,而port ...

  2. Headroom.js插件用法

    一.Headroom.js是什么? Headroom.js是一个轻量级.高性能的JS小工具(不依赖不论什么工具库.),它能在页面滚动时做出响应. 此页面顶部的导航条就是一个鲜活的案例,当页面向下滚动时 ...

  3. react-redux的connect()方法

    容器组件使用 connect() 方法连接 Redux 我们用 react-redux 提供的 connect() 方法将“笨拙”的 Counter 转化成容器组件.connect() 允许你从 Re ...

  4. windows程序设计——飞机大战笔记(Access数据库的使用)

    //////////////////2015/07/22/////////////////// /////////////////by xbw ///////////////////////// // ...

  5. WeX5开发指南

    WeX5入门.UI2开发.App开发.服务端开发.扩展资料学习. 1 新手入门 1.1 运行WeX5的demo(视频) 1.2 App开发.调试.打包部署完整过程(视频) 1.3 创建第一个应用(视频 ...

  6. 【转载】ViewState的用法

    本文导读:在web窗体控件设置为runat = "server",这个控件会被附加一个隐藏的属性_ViewState,_ViewState存放了所有控件在ViewState中的状态 ...

  7. mysql + php 中文乱码 全是? 解决方法

    在my.ini文件中找到[client]和[mysqld]字段,在下面均加上default-character-set=utf8,保存并关闭,重启服务器 在window下重启失败,这是因为你安装了高版 ...

  8. Python实战之自己主动化评论

    Python实战之自己主动化评论 玩csdn博客一个多月了,渐渐发现了一些有意思的事,常常会有人用相同的评论到处刷.不知道是为了加没什么用的积分,还是纯粹为了表达楼主好人.那么问题来了,这种无聊的事情 ...

  9. kubernetes容器探针检测

    系列目录 kubernetes提供了livenessProbe(可用性探针)和readinessProbe(就绪性探针)对容器的健康性进行检测,当然这仅仅简单的关于可用性方面的探测,实际上我们不仅仅要 ...

  10. JAVA 数据筛选(第一笔数据与第二笔数据比较)

    第一笔数据与第二笔数据比较 Map<String, Object> jHpictureMap = new HashMap<String, Object>(); // 存放照片S ...