zoukankan      html  css  js  c++  java
  • Hackerrank [World CodeSprint 11] City Construction

    传送门:https://www.hackerrank.com/contests/world-codesprint-11/challenges/hackerland

    【题解】

    因为加点每次加1个点1条边,所以不会存在一定要经过后加的那些点才能到达的情况。

    直接把最后的图建出来,tarjan缩强联通分量+拓扑排序处理连通性。

    拿个bitset维护拓扑排序过程即可。复杂度O(n^2/32)

    # include <queue>
    # include <bitset>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, m, head[M], nxt[M], to[M], tot=0, c;
    
    struct Graph {
        int head[M], nxt[M], to[M], tot;
        inline void set() {tot = 0;}
        inline void add(int u, int v) {
            ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
        }
    }G1, G;
    
    struct pa {
        int op, a, b;
    }q[M];
    
    int DFN = 0, dfn[M], low[M], bel[M], scc = 0;
    int st[M], stn=0;
    bool ins[M];
    inline void tarjan(int x) {
        dfn[x] = low[x] = ++DFN;
        st[++stn] = x;
        ins[x] = 1;
        for (int i=G1.head[x]; i; i=G1.nxt[i]) {
            if(!dfn[G1.to[i]]) {
                tarjan(G1.to[i]);
                low[x] = min(low[x], low[G1.to[i]]);
            } else if(ins[G1.to[i]]) low[x] = min(low[x], dfn[G1.to[i]]);
        }
        if(low[x] == dfn[x]) {
            int t = 0; ++scc;
            while(t != x) {
                t = st[stn];
                --stn; ins[t] = 0;
                bel[t] = scc; 
            }
        }
    }
    
    bitset<50001> bs[50001];
    int out[M], ans[M], an=0;
    queue<int> qu;
    
    int main() {
        G1.set(), G.set();
        cin >> n >> m; c = n;
        for (int i=1, u, v; i<=m; ++i) {
            scanf("%d%d", &u, &v);
            G1.add(u, v);
        }
        cin >> m;
        for (int i=1; i<=m; ++i) {
            scanf("%d%d%d", &q[i].op, &q[i].a, &q[i].b);
            if(q[i].op==1) {
                ++c;
                if(q[i].b) G1.add(c, q[i].a);
                else G1.add(q[i].a, c);
            }
        }
        for (int i=1; i<=c; ++i) if(!dfn[i]) tarjan(i);
        
    //    for (int i=1; i<=c; ++i) printf("%d
    ", bel[i]);
    
        for (int i=1; i<=c; ++i) {
            bs[bel[i]][bel[i]] = 1;
            for (int j=G1.head[i]; j; j=G1.nxt[j])  
                if(bel[i] != bel[G1.to[j]]) {
                    bs[bel[i]][bel[G1.to[j]]] = 1;
    //                printf("%d %d
    ", bel[i], bel[G1.to[j]]);
                    out[bel[i]] ++;
                    G.add(bel[G1.to[j]], bel[i]);
                }
        }
        for (int i=1; i<=scc; ++i) 
            if(!out[i]) qu.push(i);
        while(!qu.empty()) {
            int top = qu.front(); qu.pop();
            for (int i=G.head[top]; i; i=G.nxt[i]) {
                --out[G.to[i]];
                bs[G.to[i]] |= bs[top];
                if(out[G.to[i]] == 0) qu.push(G.to[i]);
            }
        }
    //    for (int i=1; i<=n; ++i, cout << endl)
    //        for (int j=1; j<=n; ++j) cout << bs[i][j] << ' ';
        
        for (int i=m; i; --i) 
            if(q[i].op == 2) ans[++an] = bs[bel[q[i].a]][bel[q[i].b]];
        
        for (int i=an; i; --i) puts(ans[i] ? "Yes" : "No");
    
        return 0;
    }
    View Code
  • 相关阅读:
    HQueue_Install_In_Ubuntu
    win10_64_ssh连接linux
    win10防火墙服务灰色解决办法
    打开houdini软件的脚本
    houdini_license_sever start and off
    Java关于Object类中equal方法的理解
    Java关于Object类中equal方法的理解
    单源最短路径
    单源最短路径
    最小生成树
  • 原文地址:https://www.cnblogs.com/galaxies/p/Hackerrank_City_Construction.html
Copyright © 2011-2022 走看看