bfs,bitset

题意:

图片说明
##分析:
题目没给数据范围,n<=2000
考录到数据范围,这题我们可以直接bfs,或者dfs。暴力搜索。
细节处理好也能过。但是,显然有些勉强。
这里面考的是,bitset容器。

bitset的或运算代替了搜索。

看代码:

bitset<max_n> a[max_n];
for (register int i = 1;i <= n;++i)
        for (register int j = 1;j <= n;++j)
            if (a[j][i])
                a[j] |= a[i];

a是邻接矩阵。。
我们看这个操作,其意义为:对n个点进行枚举i,再对n个点进行枚举j,看是否可以由j到达i。
如果可以,那么i可以到达的点j都可以到达。所以a[j]|=a[i]
很巧妙,这样操作后,不会出现漏点现象。可以画图理解一下。
用bitset的位运算代替了搜索!!!!!!

代码如下:

#include<iostream>
#include<bitset>
using namespace std;
const int max_n = 2100;
int n;
inline void write(int x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
    return;
}
inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    while (!isdigit(c)) { if (c == '-')f = -1;c = getchar(); }
    while (isdigit(c))x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return x * f;
}
bitset<max_n> a[max_n];
int main() {
    n = read();
    for (register int i = 1;i <= n;++i) {
        for (register int j = 1;j <= n;++j) {
            char ch = getchar();
            while ((ch != '0') && (ch != '1'))
                ch = getchar();
            if (ch == '1')a[i][j] = 1;
        }
    }for (register int i = 1;i <= n;++i)
        for (register int j = 1;j <= n;++j)
            if (a[j][i])
                a[j] |= a[i];
    register int ans = 0;
    for (register int i = 1;i <= n;++i)
        ans += a[i].count();
    write(ans);
}