染色标记。
判断是否是边通图,如果不是,则答案为No。
对第一个传感器能到达的非传感器的点全部染色。
对剩下的点进行查找和染色,如果找不到之前已经染色的点,则答案为No.
时间复杂度为O(e)。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
const int maxn = 100010;
struct Edge{
int v, next;
}e[maxn << 2];
int g[maxn];
int top;
void add(int u, int v)
{
e[++top].v = v;
e[top].next = g[u];
g[u] = top;
}
int ind[maxn];
int col[maxn];
int cnt;
int curv;
void dfs1(int u)
{
col[u] = 1;
for(int i = g[u]; i; i = e[i].next)
{
int v = e[i].v;
if(col[v] == 0)
dfs1(v);
}
}
bool dfs(int u, int fa)
{
if(ind[u] && col[u] == 0)
return false;
if(col[u] == 0)
cnt ++;
col[u] = 1;
bool ret = false;
for(int i = g[u]; i; i = e[i].next)
{
int v = e[i].v;
if(v != fa)
{
if(col[v] == 0)
{
ret = ret || dfs(v, u);
}
else if(v != curv)ret = true;
}
}
return ret;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
memset(g, 0, sizeof(g));
memset(col, 0, sizeof(col));
memset(ind, 0, sizeof(ind));
top = 0;
cnt = 0;
for(int i = 0; i < k; i++)
{
int kk;
scanf("%d", &kk);
ind[kk] = 1;
}
for(int i = 0; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
int l;
scanf("%d", &l);
bool ans = true;
dfs1(1);
for(int i = 1; i <= n; i++)
if(col[i] == 0){
ans = false;
break;
}
memset(col, 0, sizeof(col));
if(l != k) ans = false;
int u;
scanf("%d", &u);
col[u] = 1;
cnt ++;
dfs(u, u);
if(ind[u] == 0)
ans = false;
for(int i = 1; i < l ; i++)
{
scanf("%d", &u);
if(ind[u] == 0)
ans = false;
col[u] = 1;
cnt ++;
if(ans)
{
curv = u;
if(!dfs(u, u))
ans = false;
}
}
if(ans)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}