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. 6.【nuxt起步】-完成一个静态的页面

    1.接下来新建/component/maincontent.vue 把这些html代码copy到maincontent.vue 发现格式比较难看,就格式化一下 2.插件安装 beautify,安装后重 ...

  2. K-L变换

    K-L变换( Karhunen-Loeve Transform)是建立在统计特性基础上的一种变换,有的文献也称为霍特林(Hotelling)变换,因他在1933年最先给出将离散信号变换成一串不相关系数 ...

  3. css3 - 基本选择器

    有人说类选择器最好不要超过三层,其实我也是这样认为的,不是吗? 选择器分为四大类 标签.全选(相对于子类继承了0.1).类.ID 权值分别是:1->0.1->10->100(权值可叠 ...

  4. mysql的安装、C++訪问mysql数据库、编码设置问题

    一.mysql的安装.这个相对简单,直接去官网下载mysql安装程序.就能够完毕安装过程,网上有非常多安装教程,这个没什么注意事项. 二.C++訪问mysql.主要是用到mysql定义的头文件,内部定 ...

  5. JavaScript 内存机制

    简介 每种编程语言都有它的内存管理机制,比如简单的C有低级的内存管理基元,像malloc(),free().同样我们在学习JavaScript的时候,很有必要了解JavaScript的内存管理机制. ...

  6. 照猫画虎学gnuplot之折线图

    本节重点:怎样利用已知数据来画折线图. 首先说明:gunplot文件的后缀名为*.plt.本节讲述怎样利用已知数据来画折线图,顾名思义必定涉及到两个文件:一个是须要的数据文件,即*.dat文件.还有一 ...

  7. 1.excel如何让一列的数都乘以固定值

     让B列等于A列乘以39.37 1.我们先选中B列中要编辑的单元: 2.再在编辑栏中输入公式:=A2*39.37   (PS:*号即表示是×号) 3.公式输入后,按下快捷键:CTRL+回车:记住一定要 ...

  8. 话说Session

    Session这个概念,对于搞软件的来说,再熟悉不过了.就拿我来说,Hibernate, Shiro, Spring, JSP, Web Server等等,全都涉及到Session. 不怕笑话,一直都 ...

  9. 800元组装一台3D打印机全教程流程-零件清单

    继前面的教程800元组装一台3D打印机全教程流程 k800是一台根据kosselmini改进的低成本3d打印机,通过改变设计,降低了成本,但损失较少性能,取得性价比. 主要改动是:底部支架改为-> ...

  10. c# vs2010 连接access数据库

    第一次在博客园写博文,由于文采不怎么好,即使是自己很熟悉的东西,写起来也会感觉到不知从何讲起,我想写的多了就好了. 这篇文章主要是介绍怎么用c# 语言 vs2010连接access数据库的,连接字符串 ...