"오프 NOIP 질주 시뮬레이션 게임 소"동굴

주제 요약

주어진 \ (\ N-) 포인트 \ (m의 \) 의 그래프는, 소정 방향 가장자리가 \ (Q \) 기 질의, 주어진 각 쿼리 \ (S, T, L \) , 요청을 하나가 \ (S \)은 하기 (T \) \ 직후 경로 \ (L의 \) 측이, 패스가 반복 될 수있다 간다.
\ (N 르 100 m를 \ \ 르 10000, Q \ 르 1000 L \ 르 10 ^ 9 \)

문제 해결 아이디어

사전 배열 고려 (F [X] [I] [J] \)는 \ 여부를 나타내는을 : \ (I는 \)의\ (J \)\ (2 ^ k 개의 \) 가장자리.
이것은 바로 우리가에서 두 배 고려할 수, 플로이드를 곱 실행할 수 있습니다 \ (들의 \) 일부 노드만큼 판사 확장 한 각 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