Given a directed graph and its DFS traversal sequences, you should judge if given sequences are valid. For example, with respect to the graph below,
0 1 4 2 5 3 , 0 2 5 1 4 3 and 3 2 5 1 4 0 are all valid DFS traversal sequences, but 0 2 3 1 4 5 is not.
Input Specification:
Each input file contains one test case. For each case, the first line contains two number M (<= 100, the total count of vertices), and N (the total count of edges), separated by a space. Notice that vertices are indexed from 0 to M−1. The following N lines each give an edge in the format shown below:
ID1 ID2
It denotes a directed edge from the vertex indexed ID1 to the vertex indexed ID2. Then the next line contains a number K (<= 20, the count of sequences to be judged). And the following K lines each give a DFS traversal sequence consisting of M different numbers separated by a space.
Output Specification:
For each DFS traversal sequence to be judged, output Yes if it’s valid, No if not.
Sample Input:
6 9
0 1
0 2
0 3
2 1
3 2
4 2
1 4
2 5
4 5
3
0 1 4 2 5 3
0 2 5 1 4 3
0 2 3 1 4 5
Sample Output:
Yes
Yes
No
题意 : 给定一个有向图,和一些序列,问这些序列是不是图G
的一个dfs
遍历结果
注意 : 即使不是
从入度为0
的点开始dfs也是可以的,例如5 4 2 1 0 3
应该是yes
当一个点准备退栈,如果这个点有子节点未被访问
则这个序列不是dfs序列
#ifdef debug
#include <time.h>
#include "/home/majiao/mb.h"
#endif
#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#define MAXN ((int)1e5+7)
#define ll long long int
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for(int i=lef; i<=rig; i++)
#define forj(lef, rig) for(int j=lef; j<=rig; j++)
#define fork(lef, rig) for(int k=lef; k<=rig; k++)
#define QAQ (0)
using namespace std;
#define show(x...) \
do { \
cout << "\033[31;1m " << #x << " -> "; \
err(x); \
} while (0)
void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }
namespace FastIO {
char print_f[105];
void read() {}
void print() { putchar('\n'); }
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {
x = 0;
char ch = getchar();
ll f = 1;
while (!isdigit(ch)) {
if (ch == '-') f *= -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - 48;
ch = getchar();
}
x *= f;
read(oth...);
}
template <typename T, typename... T2>
inline void print(T x, T2... oth) {
ll p3=-1;
if(x<0) putchar('-'), x=-x;
do{
print_f[++p3] = x%10 + 48;
} while(x/=10);
while(p3>=0) putchar(print_f[p3--]);
putchar(' ');
print(oth...);
}
} // namespace FastIO
using FastIO::print;
using FastIO::read;
int n, m, Q, K, vis[MAXN], a[MAXN], ok, pn, tot, ind[MAXN];
set<int> G[MAXN];
//0 2 3 1 4 5
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
//注意点 : 即使不是从入度为0的点开始dfs也算是一个dfs序列
void dfs(int u) {
vis[u] = true;
while(pn+1<=n && !vis[a[pn+1]] && G[u].find(a[pn+1])!=G[u].end()) {
pn ++;
dfs(a[pn]);
}
// printf("u=%d: ", u);
// for(auto v : G[u]) printf("(v:%d vis:%d), ", v, vis[v]);
// printf("\n");
for(auto v : G[u]) //检查是否所有u的子节点都访问完了
if(!vis[v]) ok = false; //有未访问的子节点,输出No
}
bool check() {
memset(vis, false, sizeof(vis));
pn = tot = 0;
ok = true;
while(++pn <= n) {
if(!vis[a[pn]]) dfs(a[pn]);
}
return ok;
}
int main() {
#ifdef debug
freopen("test", "r", stdin);
clock_t stime = clock();
#endif
read(n, m);
for(int i=1; i<=m; i++) {
int u, v;
read(u, v);
G[u].insert(v);
ind[v] ++;
}
read(m);
while(m--) {
for(int i=1; i<=n; i++) read(a[i]);
bool ok = check();
printf("%s\n", ok ? "Yes" : "No");
}
#ifdef debug
clock_t etime = clock();
printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif
return 0;
}