[JSOI2010]连通数

[JSOI2010]连通数

https://ac.nowcoder.com/acm/problem/20187

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);
}
全部评论

相关推荐

07-17 11:56
门头沟学院 Java
感谢东子的收留
熬夜脱发码农:无敌了,这是我看到第二个京东的提前批大佬了我还在畏畏缩缩准备八股算法
点赞 评论 收藏
分享
06-15 02:05
已编辑
南昌航空大学 数据分析师
Eason三木:你如果想干技术岗,那几个发公众号合唱比赛的经历就去掉,优秀团员去掉,求职没用。然后CET4这种不是奖项,是技能,放到下面的专业技能里或者单独列一个英语能力。 另外好好改改你的排版,首行缩进完全没有必要,行间距好好调调,别让字和标题背景黏在一起,你下面说能做高质量PPT你得展现出来啊,你这简历排版我用PPT做的都能比你做的好。 然后自我评价,你如果要干数据工程师,抗压能力强最起码得有吧。
简历中的项目经历要怎么写
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务