题意: 给定一个图和若干放置了传感器的点,问能否遍历图并按照给定的顺序访问传感器 。
显然,我们一要判断图的连通性,二要判断是否按照所给顺序访问传感器 。
其实用dfs捎带着就可以判断了连通性,不用再另写并查集, 重点是怎么判断顺序 : 我们不妨按照顺序来依次DFS, 如果遇到传感器,那么就返回,不再搜索并将该点置零,这样,如果搜索到的这个传感器是下一个传感器,那么下一次dfs的传感器应该已经标记为0 。注意,由于传感器只记录第一次到达的时间,所以可以重复经过一个已经走过的传感器,因此这个方法才是对的 。 另外根据题意, k和l 必须是相等的 。
#include<bits/stdc++.h>
using namespace std;
const int max_e = 100000 + 10;
int T,n,m,a,b,k,l,vis[max_e],e[max_e],es[max_e],path[max_e],cnt1,cnt2;
vector<int> g[max_e];
void init() {
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) {
g[i].clear();
vis[i] = 0; es[i] = 0;
}
for(int i=0;i<k;i++) {
scanf("%d",&a);
es[a] = 1;
}
for(int i=0;i<m;i++) {
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]);
}
cnt1 = cnt2 = 0;
}
void dfs(int cur) {
for(int i=0;i<g[cur].size();i++) {
int u = g[cur][i];
if(!vis[u]) {
vis[u] = 1;
cnt1++;
if(es[u]) {
es[u] = 0;
cnt2++;
}
else dfs(u);
}
}
}
int main() {
scanf("%d",&T);
while(T--) {
init();
if(l == k) {
cnt1 = cnt2 = 1;
vis[path[0]] = 1;
es[path[0]] = 0;
for(int i=0;i<l;i++) {
if(es[path[i]]) break;
else dfs(path[i]);
}
}
if(l == k && cnt1 == n && cnt2 == l) printf("Yes\n");
else printf("No\n");
}
return 0;
}