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
原文地址:https://www.cnblogs.com/galaxies/p/Hackerrank_City_Construction.html