zoukankan      html  css  js  c++  java
  • BZOJ2208: [Jsoi2010]连通数(tarjan bitset floyd)

    题意

    题目链接

    Sol

    数据水的一批,(O(n^3))暴力可过

    实际上只要bitset优化一下floyd复杂度就是对的了((O(frac{n^3}{32})))

    还可以缩点之后bitset维护一下连通性,然后对每个联通块之间的分别算,复杂度是(O(frac{nm}{32}))(好像和上面的没区别。。。)

    上面代码是floyed

    下面的是tarjan

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 2001;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    } 
    int N;
    char s[MAXN];
    bitset<MAXN> f[MAXN];
    int main() {
        N = read();
        for(int i = 1; i <= N; i++) {
            scanf("%s", s + 1);
            for(int j = 1; j <= N; j++) f[i][j] = (s[j] == '1' || (i == j));
        }
        for(int k = 1; k <= N; k++) 
            for(int i = 1; i <= N; i++) 
                if(f[i][k]) f[i] = f[i] | f[k];
        int ans = 0;
        for(int i = 1; i <= N; i++) ans += f[i].count();
        cout << ans;
        return 0;;
    }
    
    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 4001;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    } 
    int N, dfn[MAXN], low[MAXN], tot, vis[MAXN], col[MAXN], siz[MAXN], cnt, inder[MAXN];
    stack<int> s;
    char str[MAXN];
    bitset<MAXN> f[MAXN];
    vector<int> v[MAXN], E[MAXN];
    void tarjan(int x) {
        dfn[x] = low[x] = ++tot; vis[x] = 1; s.push(x);
        for(int i = 0; i < v[x].size(); i++) {
            int to = v[x][i];
            if(!dfn[to]) tarjan(to), low[x] = min(low[x], low[to]);
            else if(vis[to]) low[x] = min(low[x], dfn[to]);
        }
        if(low[x] == dfn[x]) {
            int h; cnt++;
            do {
                h = s.top(); s.pop(); vis[h] = 0;
                col[h] = cnt; siz[cnt]++;
            }while(h != x);
        }
    }
    void Topsort() {
        queue<int> q;
        for(int i = 1; i <= cnt; i++) {
            f[i][i] = 1; 
            if(!inder[i]) q.push(i);
        }
        while(!q.empty()) {
            int p = q.front(); q.pop(); 
            for(int i = 0; i < E[p].size(); i++) {
                int to = E[p][i]; f[to] |= f[p];
                if(!(--inder[to])) q.push(to);
            }
        }
        int ans = 0;
        for(int i = 1; i <= cnt; i++) {
            for(int j = 1; j <= cnt; j++) {
                if(f[i][j]) ans += siz[i] * siz[j];
            }
        }
        printf("%d
    ", ans);
    }
    int main() {
        N = read();
        for(int i = 1; i <= N; i++) {
            scanf("%s", str + 1);
            for(int j = 1; j <= N; j++) if(str[j] == '1' || (i == j)) v[i].push_back(j);
        }
        for(int i = 1; i <= N; i++) 
            if(!dfn[i]) 
                tarjan(i);
        for(int i = 1; i <= N; i++) {
            for(int j = 0; j < v[i].size(); j++) {
                int to = v[i][j];
                if(col[to] != col[i]) E[col[to]].push_back(col[i]), inder[col[i]]++;
            }
        }
        Topsort();
        return 0;;
    }
    
  • 相关阅读:
    Intellij IDEA debug jar包
    diamond简介和使用
    dubbo配置指南
    dubbo简单配置与使用
    设计模式之策略模式
    悲观锁和乐观锁
    sql建表,建索引注意事项
    jvm 调优(2)垃圾回收算法
    jvm 调优(1)概念
    jvm 命令
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/10275234.html
Copyright © 2011-2022 走看看