题目链接

先缩点,对于scc之间贡献即为szscc[i]*szscc[j]

用f[i][j]表示scci是否能到sccj

拓扑排序,每次把now的f或上to的f

用bitset优化

//63888kb	1080ms
#include <cstdio>
#include <cctype>
#include <bitset>
#include <algorithm>
#define gc() getchar()
const int N=2005,M=4e6+5; int n,bel[N],Enum,H[N],Snum,Sh[N];
int cnt,dgr[N],sz[N],dfn[N],low[N],id,sk[N],top,q[N];
bool ins[N];
char s[N];
std::bitset<N> f[N];
struct Edge
{
int nxt,to;
}e[M],se[M]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v){
e[++Enum].to=v, e[Enum].nxt=H[u], H[u]=Enum;
}
inline void AddEdge2(int u,int v){
++dgr[v];
se[++Snum].to=v, se[Snum].nxt=Sh[u], Sh[u]=Snum;
}
void Tarjan(int x)
{
dfn[x]=low[x]=++id, sk[++top]=x, ins[x]=1;
for(int v,i=H[x]; i; i=e[i].nxt)
if(!dfn[v=e[i].to])
Tarjan(v), low[x]=std::min(low[x],low[v]);
else if(ins[v])
low[x]=std::min(low[x],dfn[v]);
if(dfn[x]==low[x])
{
++cnt;
do{
bel[sk[top]]=cnt, ++sz[cnt];
ins[sk[top--]]=0;
}while(x!=sk[top+1]);
}
}
void Rebuild()
{
for(int x=1; x<=n; ++x)
for(int i=H[x]; i; i=e[i].nxt)
if(bel[e[i].to]!=bel[x]) AddEdge2(bel[e[i].to],bel[x]);//反向
}
int Solve()//cnt与n别混
{
int h=0,t=0;
for(int i=1; i<=cnt; ++i)
if(!dgr[i]) q[t++]=i;
for(int i=1; i<=cnt; ++i) f[i][i]=1;
while(h<t)
{
int x=q[h++];
for(int i=Sh[x]; i; i=se[i].nxt)
{
if(!--dgr[se[i].to]) q[t++]=se[i].to;
f[se[i].to]|=f[x];
}
}
int res=0;
for(int i=1; i<=cnt; ++i)
for(int j=1; j<=cnt; ++j)
if(f[i][j]) res+=sz[i]*sz[j];
return res;
} int main()
{
n=read();
for(int i=1; i<=n; ++i)
{
scanf("%s",s+1);
for(int j=1; j<=n; ++j)
if(s[j]=='1') AddEdge(i,j);
}
for(int i=1; i<=n; ++i)
if(!dfn[i]) Tarjan(i);
Rebuild();
printf("%d",Solve()); return 0;
}

BZOJ.2208.[JSOI2010]连通数(bitset Tarjan 拓扑)的更多相关文章

  1. bzoj 2208: [Jsoi2010]连通数【tarjan+拓扑+dp】

    我总觉得枚举点bfs也行-- tarjan缩点,记一下每个scc的size,bitset压一下scc里的点,然后按拓扑倒序向上合并到达状态,然后加ans的时候记得乘size #include<i ...

  2. BZOJ 2208: [Jsoi2010]连通数 tarjan bitset

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  3. bzoj 2208 [Jsoi2010]连通数

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 输入数据第一行是图顶点的数量,一个正整数N ...

  4. BZOJ 2208: [Jsoi2010]连通数( DFS )

    n只有2000,直接DFS就可以过了... -------------------------------------------------------------------------- #in ...

  5. BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序

    题目大意:给定一个n个点的有向图,求有多少点对(x,y),使x沿边可到达y 设f[i][j]为从i到j是否可达 首先强联通分量中的随意两个点均可达 于是我们利用Tarjan缩点 缩点之后是一个拓扑图. ...

  6. 2208: [Jsoi2010]连通数

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1371  Solved: 557[Submit][Status ...

  7. 【BZOJ2208】[JSOI2010]连通数(Tarjan)

    [BZOJ2208][JSOI2010]连通数(Tarjan) 题面 BZOJ 洛谷 题解 先吐槽辣鸡洛谷数据,我写了个\(O(nm)\)的都过了. #include<iostream> ...

  8. 2208: [Jsoi2010]连通数 - BZOJ

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

  9. 【BZOJ】2208 [Jsoi2010]连通数

    [题意]给定n个点的有向图,求可达点对数(互相可达算两对,含自身).n<=2000. [算法]强连通分量(tarjan)+拓扑排序+状态压缩(bitset) [题解]这题可以说非常经典了. 1. ...

随机推荐

  1. 【转】Shell编程基础篇-下

    [转]Shell编程基础篇-下 1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 ...

  2. (DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device【转】

    转自:https://blog.csdn.net/lichengtongxiazai/article/details/38942033 Linux kernel 是怎么将 devicetree中的内容 ...

  3. Linux系统调用的运行过程【转】

    本文转自:http://blog.csdn.net/kernel_learner/article/details/7331505 在Linux中,系统调用是用户空间访问内核的唯一手段,它们是内核唯一的 ...

  4. python中的这些坑,早看早避免。

    python中的这些坑,早看早避免. 说一说python中遇到的坑,躲坑看这一篇就够了 传递参数时候不要使用列表 def foo(num,age=[]): age.append(num) print( ...

  5. 【转】C语言正确使用extern关键字

    利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下. 一.引用同一个文件中的变量 #include<stdio.h> int f ...

  6. 转载:JAVA序列化与反序列化 (作者:YSOcean)

    原文:https://www.cnblogs.com/ysocean/p/6870069.html File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878 ...

  7. oracle 各个版本下载地址

    Oracle9i Database Release 2 Enterprise/Standard/Personal Edition for Windows NT/2000/XP http://downl ...

  8. hdu2289二分答案 圆台体积

    精度小一点就能过 #include<bits/stdc++.h> #define maxn 1000000009 #define esp 1e-9 #define PI 3.1415926 ...

  9. hdu3183 rmq求区间最值的下标

    两个月前做的题,以后可以看看,是rmq关于求区间最值的下标 /* hdu3183 终点 给一个整数,可以删除m位,留下的数字形成一个新的整数 rmq 取n-m个数,使形成的数最小 */ #includ ...

  10. cf1061D 贪心+multiset 好题!

    cf上的思维题真好! 本题是在模拟的基础上贪心即可:将n段时间按照左端点(右端点为第二关键字)从小到大排序,然后遍历每一个时间段. 对于每一个时间段[li,ri],先找到multiset中最靠近li但 ...