此题做法是用dfs从该点拓展到所有可达的传感器,然后在数轴上标记,这次可达,就算之后传感器不是他,之后的每一次都是可达到他的,因为可以往回走,因为所有的点被访问一次都就不需要再次访问了,所以复杂度是o(N)的,然后还需要先用并查集去判断所有点是不是在一个连通块里,因为如果不在一个连通块就不可能到达所有的点,我做的时候的错误是只用并查集去判断先后顺序的2个传感器是不是在一个连通块,但是这样会出现一个不是传感器的点不属于大的连通块,但是所有传感器都属于大的连通块,那么还是不能到达所有点。。真是太粗心了。
AC代码:
#include<cstdio>
#include<ctype.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdlib>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<ctime>
#include<string.h>
#include<string>
using namespace std;
#define ll long long
#define eps 1e-8
#define MOD 1000000007
template<class T>
inline void scan_d(T &ret)
{
char c;
ret=0;
while((c=getchar())<'0'||c>'9');
while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
}
int pa[100005],b[100005];
int findset(int x){return pa[x] != x ? pa[x] = findset(pa[x]):x;}
vector<int>a[100005];
bool mark[100005],flag[100005],s[100005];
void dfs(int x)
{
int sz = a[x].size();
flag[x] = 1;
for(int i = 0; i < sz; i++) if(!flag[a[x][i]])
{
if(mark[a[x][i]]) s[a[x][i]] = 1;
else dfs(a[x][i]);
}
}
int main()
{
#ifdef GLQ
freopen("input.txt","r",stdin);
// freopen("o2.txt","w",stdout);
#endif // GLQ
int t,n,m,k,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
memset(mark,0,sizeof(mark));
memset(flag,0,sizeof(flag));
memset(s,0,sizeof(s));
for(i = 1; i <= n; i++)
{
a[i].clear();
pa[i] = i;
}
for(i = 0; i < k; i++)
{
int t;
scan_d(t);
mark[t] = 1;
}
for(i = 0; i < m; i++)
{
int x,y;
scan_d(x);
scan_d(y);
a[x].push_back(y);
a[y].push_back(x);
x = findset(x);
y = findset(y);
pa[x] = y;
}
int l;
scanf("%d",&l);
for(i = 0; i < l; i++)
{
scan_d(b[i]);
}
if(l < k)
{
printf("No\n");
continue;
}
int ans = 1;
int w = findset(1);
for(i = 2; i <= n; i++) if(w!=findset(i))
{
ans = 0;
break;
}
if(ans==0)
{
printf("No\n");
continue;
}
for(i = 0; i < l-1; i++)
{
dfs(b[i]);
if(s[b[i+1]]==0)
{
ans = 0;
break;
}
}
if(ans) printf("Yes\n");
else printf("No\n");
}
}