题目大意:给出n个点,m条边,k个传感器放在k个点上,按一定顺序经过L个传感器,每个传感器只能经过一次,问能够按这个顺序经过这L个传感器,并且遍历到每个点。
分析:DFS。首先,如果L不等于k的话,则说明有某点没有遍历到,答案自然是No。接着,从第一个位置的传感器,开始深搜,当搜到一个新的传感器时,停止这条边搜索,并将这个新的传感器记录为已访问。然后,再按顺序搜下一个传感器,如果,这个传感器之前没被搜索到,说明这个顺序是不正确的。因为,按正确的顺序搜,下一个传感器应该是上一次搜到的新的。
最后,如果没有遍历到所有的点,说明图不连通,答案也是No
代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 111111;
vector<int> g[maxn];
int sen[maxn];
int path[maxn];
int vis[maxn];
int n, m, k, l;
int cnt1, cnt2;
void dfs(int u) {
int len = g[u].size();
for(int i = 0; i < len; i++) {
int v = g[u][i];
if(!vis[v]) {
vis[v] = 1;
cnt2++;
if(sen[v]) {
sen[v] = 0;
cnt1++;
}
else dfs(v);
}
}
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d", &n, &m, &k);
for(int i = 0; i <= n; i++) {
g[i].clear();
vis[i] = 0;
sen[i] = 0;
}
for(int i = 0; i < k; i++) {
int a;
scanf("%d", &a);
sen[a] = 1;
}
for(int i = 0; i < m; i++) {
int a, b;
scanf("%d%d", &a, &b);
g[a].push_back(b);
g[b].push_back(a);
}
scanf("%d", &l);
for(int i = 0; i < l; i++)
scanf("%d", &path[i]);
if(l != k) {
printf("No\n");
continue;
}
sen[path[0]] = 0;
vis[path[0]] = 1;
cnt1 = cnt2 = 1;
for(int i = 0; i < l; i++) {
if(sen[path[i]]) break;
else dfs(path[i]);
}
if(cnt1 == l && cnt2 == n)
printf("Yes\n");
else printf("No\n");
}
return 0;
}