[JSOI2010] 连通数
Description

Input
输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。
Output
输出一行一个整数,表示该图的连通数。
HINT
对于100%的数据,N不超过2000。
Solution
\(Tarjan\) 缩点 \(+\) 拓扑排序 \(+\) \(bitset\) 优化状压
显然对于每个强联通分量我们都要求出在新图上它能到达哪些点。
如何求呢?
法一: \(dfs\),对于每个强联通分量找一下它连出去的边能到达哪些联通块,统计答案即可。复杂度 \(O(n^2)\)。(只是口胡一下没有写这种方法如果写不出来别找我)
法二:我们定义数组 \(f[i][j]\) 表示能否从第 \(i\) 个连通分量到达第 \(j\) 个连通分量。因为值只能为 \(0/1\),我们用 \(bitset\) 来状压第二维。因为 \(f[j]=or(f[i]),j\;can\;go\;to\;i\),所以我们在新图上建立一张反图,拓扑排序,按照拓扑序即可求出每个点能到达哪些点。 复杂度 \(O(n^2/32)\)。
Code
#include<queue>
#include<bitset>
#include<cstdio>
#include<cctype>
#include<iostream>
#define N 2005
#define min(A,B) ((A)<(B)?(A):(B))
int ans;
char ch[N];
bool in[N];
int n,cnt,sum,tot;
int dfn[N],low[N];
std::bitset<N> f[N];
std::queue<int> topo;
int belong[N],deg[N];
int head[N],head2[N];
int stk[N],top,sze[N];
struct Edge{
int to,nxt;
}edge[N*N],edge2[N*N];
void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
}
void add2(int x,int y){
edge2[++cnt].to=y;
edge2[cnt].nxt=head2[x];
head2[x]=cnt;
}
int getint(){
int x=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x;
}
void tarjan(int now){
dfn[now]=low[now]=++sum;
stk[++top]=now;in[now]=1;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(!dfn[to]){
tarjan(to);
low[now]=min(low[now],low[to]);
}
else if(in[to])
low[now]=min(low[now],dfn[to]);
}
if(low[now]==dfn[now]){
int y; tot++;
do{
y=stk[top--];
belong[y]=tot;
sze[tot]++;
in[y]=0;
}while(y!=now);
}
}
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",ch);
for(int j=0;j<n;j++){
if(ch[j]=='0') continue;
add(i,j+1);
}
}
cnt=0;
for(int i=1;i<=n;i++){
if(!dfn[i])
tarjan(i);
}
for(int x=1;x<=n;x++){
for(int i=head[x];i;i=edge[i].nxt){
int to=edge[i].to;
if(belong[x]==belong[to]) continue;
deg[belong[x]]++;
add2(belong[to],belong[x]);
}
}
for(int i=1;i<=tot;i++)
f[i][i]=1;
for(int i=1;i<=tot;i++){
if(!deg[i])
topo.push(i);
}
while(topo.size()){
int u=topo.front();topo.pop();
for(int i=head2[u];i;i=edge2[i].nxt){
int to=edge2[i].to;
deg[to]--;
f[to]|=f[u];
if(!deg[to])
topo.push(to);
}
}
for(int i=1;i<=tot;i++){
for(int j=1;j<=tot;j++){
if(f[i][j])
ans+=sze[i]*sze[j];
}
}
printf("%d\n",ans);
return 0;
}
[JSOI2010] 连通数的更多相关文章
- BZOJ 2208: [Jsoi2010]连通数 tarjan bitset
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- bzoj2208:[Jsoi2010]连通数
http://blog.csdn.net/u013598409/article/details/47037499 里面似乎有生成数据的... //我本来的想法是tarjan缩点之后然后将图遍历一遍就可 ...
- bzoj2208 [Jsoi2010]连通数(scc+bitset)
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1879 Solved: 778[Submit][Status ...
- BZOJ 2208: [Jsoi2010]连通数( DFS )
n只有2000,直接DFS就可以过了... -------------------------------------------------------------------------- #in ...
- 2208: [Jsoi2010]连通数
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1371 Solved: 557[Submit][Status ...
- bzoj 2208 [Jsoi2010]连通数
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 输入数据第一行是图顶点的数量,一个正整数N ...
- 【BZOJ2208】[JSOI2010]连通数(Tarjan)
[BZOJ2208][JSOI2010]连通数(Tarjan) 题面 BZOJ 洛谷 题解 先吐槽辣鸡洛谷数据,我写了个\(O(nm)\)的都过了. #include<iostream> ...
- 【BZOJ2208】[Jsoi2010]连通数 DFS
[BZOJ2208][Jsoi2010]连通数 Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示 ...
- 【bzoj2208】[Jsoi2010]连通数
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2305 Solved: 989[Submit][Status ...
- 暴力【bzoj2208】: [Jsoi2010]连通数
2208: [Jsoi2010]连通数 暴力过的. 没脸说... 正解好像是缩点+递推. 应该也不难写. code: #include <iostream> #include <cs ...
随机推荐
- AX_List
List list = new List(Types::Class); CustTable custTable; while select custTable { list.addEn ...
- 2019.02.21 bzoj2829: 信用卡凸包(凸包)
传送门 题意:给nnn个A∗BA*BA∗B的矩形,其中每个矩形的四个角被改造成了半径为rrr的四分之一 圆,问这些矩形的凸包周长. 思路:考虑求出圆心的凸包周长然后加上一个整圆的周长,证明很简单,略掉 ...
- 综合数据api接口使用
由于请求数据接口是跨域的,但是我们无法改变接口的代码 先从请求后台,然后从后台进行二次请求,请求数据接口 原生代码 package edu.nf.http.test; import org.apach ...
- nginx启动或者重启失败,报错nginx: [error] open() "/usr/local/var/run/nginx.pid" failed (2: No such file or directory)
第一种方案: 1. 执行命令 :open /usr/local/etc/nginx 打开nginx安装目录 nginx安装目录默认位置有:(找到适合你的) /etc/nginx/nginx.conf, ...
- 向Word添加一段文本
文档层次结构 [段落之后] 是一段连续文本,它定义具有一组常见属性的文本区域.一段连续文本由 r 元素表示,这样创建器便可组合换行.样式或格式设置属性,从而将相同信息应用于一段连续文本的所有部分. 正 ...
- 利用ONENET平台控制MPC
可以用于广告机或者灾害预警,实时广播等行业 这个分控制端和服务端 控制端采用winform编写,服务端采用控制台程序编写 优点在于服务端不用有公网ip,比传统方案方便的多. 也不用租用费用高额的云服务 ...
- hadoop2.4.0伪分布式搭建以及分布式关机重启后datanode没起来的解决办法
1.准备Linux环境 1.0点击VMware快捷方式,右键打开文件所在位置 -> 双击vmnetcfg.exe -> VMnet1 host-only ->修改subnet ip ...
- python 使用unittest进行单元测试
import unittest import HTMLTestRunner """ Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面 ...
- antd在webpack里面的配置
概述 antd是蚂蚁金服打造的一个react组件,真的非常棒,我看了下官方文档,感觉比bootstrap要好.唯一的缺点可能就是打包的时候要打包它的一些样式表,所以资源体积会很大,并且css可能会和自 ...
- 如何完美回答面试官问的Mybatis初始化原理!!!
前言 对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程. MyBatis的初始化做了什么 MyBatis基于XML配置文件 ...