「牛オフNOIPスプリントシミュレーションゲーム」洞窟

トピックの概要

所与の\(\ N-)点、\(m個\)グラフは、所与の有向エッジを有する\(Q \)グループクエリ、与えられた各クエリ\(S、T、L \) 依頼を以下からのものがある\(S \)する(T \)\直後のパスを\(Lの\)側が、経路が繰り返されてもよい進みます。
\(Nル100、M \ル10 ^ 9 \ L \ \ル10000、Q \ル1000)

問題解決のためのアイデア

プレ配列考える(F [X] [I]、[J] \)は\かどうかを示した:\(私は\)が来る\(J \)\(2 ^ k個の\)エッジを。
これはフロイドを掛け、その後、我々は2倍にすることから検討することができ、直接実行することができます\(S \)各BFSの始まりは限り裁判官として、いくつかのノードを拡張してきた\(のt \)は、ノードの最後のセットに属します。

詳細注意事項

  • いくつかの他の方法は、多くの場合、妖精として、カードを必要とするかもしれない\(O(\ FRAC {N ^ 3}、{64} Qの\ LOG_ {256} L)\)

参照コード

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cmath>
#include <ctime>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < typename T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= c == '-', c = getchar();
    while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    s = f ? -s : s;
}

const int _ = 102;

int n, m, f[31][_][_], vis[_];
vector < int > vec;

inline void expand(int x) {
    memset(vis, 0, sizeof (int) * (n + 1));
    for (rg int i = 1; i <= n; ++i)
        for (rg int j = 0; j < vec.size(); ++j)
            if (f[x][vec[j]][i]) { vis[i] = 1; break; }
    vec.clear();
    for (rg int i = 1; i <= n; ++i) if (vis[i]) vec.push_back(i);
}

inline void solve() {
    int l, x, y; read(l), read(x), read(y);
    vec.clear(); vec.push_back(x);
    for (rg int i = 30; ~i; --i)
        if (l >> i & 1) expand(i);
    for (rg int i = 0; i < vec.size(); ++i)
        if (vec[i] == y) { puts("YES"); return; }
    puts("NO");
}

int main() {
//  file("cave");
    read(n), read(m);
    for (rg int u, v, i = 1; i <= m; ++i)
        read(u), read(v), f[0][u][v] = 1;
    for (rg int x = 1; x <= 30; ++x)
        for (rg int k = 1; k <= n; ++k)
            for (rg int i = 1; i <= n; ++i)
                for (rg int j = 1; j <= n; ++j)
                    f[x][i][j] |= f[x - 1][i][k] & f[x - 1][k][j];
    int T; read(T);
    while (T--) solve();
    return 0;
}

エンドSahua \(qwq \)

おすすめ

転載: www.cnblogs.com/zsbzsb/p/11759797.html