bzoj2208
floyde+bitset
可以用tarjan+递推,复杂度n+m
但是我们也可以用传递闭包+bitset,复杂度n^3/32
就是通常floyde是k=1->n i=1->n j=1->n f[i][j] |= f[i][k] * f[k][j]但是我们发现floyde的两维数组可以用bitset表示,前两层枚举是不可避免的,最后枚举j其实可以用bitset处理,如果i和k联通,那么f[i][k]肯定是1,剩下的就是判断k和哪些点联通,那么原来是枚举,现在bitset|一下就可以了,直接就找到了,复杂度降低了
#include<bits/stdc++.h> using namespace std; const int N = 2010; int n; bitset<N> g[N]; char s[N]; int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) { g[i][i] = 1; scanf("%s", s + 1); for(int j = 1; j <= n; ++j) if(s[j] == '1') g[i][j] = 1; } for(int k = 1; k <= n; ++k) for(int i = 1; i <= n; ++i) if(g[i][k]) g[i] |= g[k]; int ans = 0; for(int i = 1; i <= n; ++i) ans += g[i].count(); printf("%d\n", ans); return 0; }