Topic Summary
Given a \ (n-\) points, \ (m \) have edges directed graph, given \ (Q \) group query, each query given \ (S, T, L \) , asks is there one from \ (S \) to \ (T \) path just after \ (L \) sides, goes a path may be repeated.
\ (n \ le 100, m \ le 10000, Q \ le 1000, l \ le 10 ^ 9 \)
Problem-solving ideas
Consider a pre-array \ (F [X] [I] [J] \) : indicates whether the \ (I \) come \ (J \) after \ (2 ^ k \) edges.
This can be run directly multiply Floyd, then we can consider doubling from \ (s \) the beginning of each bfs have extended some nodes, as long as the judge \ (t \) belongs to the last set of nodes.
Details Notes
- Some other methods may often require card, such as a fairy \ (O (\ frac {n ^ 3} {64} Q \ log_ {256} l) \)
Reference Code
#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;
}
End Sahua \ (qwq \)