https://www.luogu.org/problem/show?pid=3144#sub
分析:按顺序去掉点后查询图是否还是联通的,那么我们就可以按照删除的顺序倒着加点。
在加某个点之前判断图是否是联通的,即按顺序去掉这个点后图是否是联通的。
具体的处理方法:根据输出要求,我们可以先把最后一个去掉的点加进图中;然后在倒着放入其它点
(第i个点)之前先判断当前图是否是联通的,将答案存入ans[i+1]中,当i为0时,只判断图是否是联通的,
然后break掉就可以了。
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
vector <int> to[3009];
int n,m,p[3009],f[3009];
string ans[3009];
bool vis[3009];
vector <int> q;
int find(int x)
{
return x==f[x]?x:f[x]=find(f[x]);
}
void add(int x)
{
for(int i=0;i<to[x].size();i++)
if(vis[to[x][i]]) f[find(x)]=find(to[x][i]);
q.push_back(x);
vis[x]=1;
}
bool judge()
{
if(!q.size()) return true;
else{
int fa=find(q[0]);
for(int i=1;i<q.size();i++)
{
int k=q[i];
if(find(k)!=fa)
return false;
}
}
return true;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
to[x].push_back(y);
to[y].push_back(x);
}
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
add(p[n]);
for(int i=n-1;i>=0;i--)
{
if(judge()) ans[i+1]="YES";
else ans[i+1]="NO";
if(i==0) break;
add(p[i]);
}
for(int i=1;i<=n;i++)
cout<<ans[i]<<endl;
return 0;
}