题意:给若N点以及其相互之间的连接关系【双向边】。又K个点的遍历顺序(第一次到达某点的顺序)。问是否能按照该顺序遍历图中所有的点
题解:如果l<k的话是一定不可能有解的[k个传感器中一定有点没有遍历到]。
使用并查集,先将两端都没有传感器的边加入图中,而后按照遍历顺序将 有传感器的点以及以它为端点,另一端【已经遍历的有传感器的点和没有传感器的点】 一个个加入图中,判断是否与之前的图连通即可...[代码不能更丑][Chaos Head]
#include <bits/stdc++.h>
using namespace std;
int father[110000];
int GetFather(int x)
{
if (father[x]==x)
return x;
else
{
int t=GetFather(father[x]);
father[x]=t;
return t;
}
}
int n,m,k,l;
vector<int>a[110000],r;
bool vis[110000],vised[110000];
void Gao()
{
cin>>n>>m>>k;
memset(vis,0,sizeof(vis));
memset(vised,true,sizeof(vised));
for (int i=0;i<=n;i++)
a[i].clear(),father[i]=i;
for (int i=0;i<k;i++)
{
int x;
scanf("%d",&x);
vis[x]=true;
vised[x]=false;
}
for (int i=0;i<m;i++)
{
int x,y;
scanf("%d %d",&x,&y);
a[x].push_back(y);
a[y].push_back(x);
} int tem=0;
for (int i=1;i<=n;i++)
{
if (vis[i])
continue;
for(int j=0;j<a[i].size();j++)
{
if (!vis[a[i][j]])
{
int fa,fb;
fa=GetFather(i);
fb=GetFather(a[i][j]);
if (fa!=fb)
father[fa]=fb,tem++;
}
}
}
cin>>l;
r.clear();
for (int i=0;i<l;i++)
{
int x;scanf("%d",&x);
r.push_back(x);
}
if (l<k)
{
cout<<"No"<<endl;
return ;
}
for (int i=0;i<l;i++)
{
vised[r[i]]=true;
for (int j=0;j<a[r[i]].size();j++)
{
int fa,fb;
if (!vised[a[r[i]][j] ] )
continue;
fa=GetFather(r[i]);
fb=GetFather(a[r[i]][j]);
if (fa!=fb)
father[fa]=fb;
}
if((i>=1)&&(GetFather(r[i])!=GetFather(r[i-1])))
{
cout<<"No"<<endl;return;
}
}
for (int i=2;i<=n;i++)
{
if (GetFather(i)!=GetFather(1))
{
cout<<"No"<<endl;
return ;
}
}
cout<<"Yes"<<endl;
}
int main()
{
int T;
cin>>T;
while (T--)
Gao();
return 0;
}