https://www.luogu.org/problem/show?pid=3144
可以考虑从询问反过来加边,注意加的边一定要两个顶点都存在
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ms(i,j) memset(i,j, sizeof i);
using namespace std;
struct ed
{
int x,y;
}edge[3005];
int father[3005];
int find(int x)
{
if (father[x]!=x) return father[x] = find(father[x]);
else return father[x];
}
int merge(int x, int y)
{
father[x] = y;
}
int ord[3005];
bool ans[3005];
bool vi[3005];
int n,m;
int main()
{
scanf("%d%d", &n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d", &edge[i].x, &edge[i].y);
}
for (int i=1;i<=n;i++) scanf("%d", &ord[i]);
printf("YES\n");
for (int j=1;j<=n;j++) father[j]=j; ms(vi,false);
for (int i=n;i>1;i--)
{
ans[i] = true; vi[ord[i]] = true;
for (int j=1;j<=m;j++)
{
ed E = edge[j];
if (E.x==ord[i]||E.y==ord[i])
{
if (E.x==ord[i]) if (!vi[E.y]) continue;
if (E.y==ord[i]) if (!vi[E.x]) continue;
int a = find(E.x);
int b = find(E.y);
if (a!=b) merge(a,b);
}
}
for (int j=1;j<=n;j++) find(j);
int cnt = 0;
int y = father[ord[i]];
for (int j=1;j<=n;j++)
{
if (!vi[j]) continue;
if (y!=father[j]) cnt++;
}
if (cnt!=0) ans[i] = false;
}
for (int i=2;i<=n;i++)
if (ans[i]) printf("YES\n"); else printf("NO\n");
return 0;
}