题意简述
给定 N N N 个点和 Q Q Q 次操作,操作分为两种:
- 在点 x x x 和 y y y 之间连一条边(保证这两个点之前不相连)。
- 去掉所有与点 x x x 相连的边。
要求在每次操作后输出没有任何边的点的个数(边数为 0 0 0 的点的个数)。
解题思路
由于删除边的操作很难处理,所以考虑用集合进行删除边的操作,再开一个数组记录每个点当前状态是否为没有边即可。
对点 x x x 进行删除操作时,由于边是双向的,只需遍历点 x x x 连接的所有点 y y y,再在 y y y 中删除 x x x 即可。注意判断 y y y 删除 x x x 之后的状态,是否变为没有边的点了。
AC代码
#include<bits/stdc++.h>
using namespace std;
set<int> s[300010];
int n,q,ans=0;
int vis[300010];
int main(){
cin>>n>>q;
ans=n;//初始所有点都没有边
while(q--){
int o,x,y;
cin>>o;
if(o==1){
cin>>x>>y;
s[x].insert(y);
s[y].insert(x);
//连接后计算当前答案
ans-=(1-vis[x])+(1-vis[y]);
vis[x]=vis[y]=1;
}else{
cin>>x;
for(set<int>::iterator it=s[x].begin();it!=s[x].end();it++){
//遍历set,删掉有关x的边
s[*it].erase(x);
if(s[*it].empty()){
ans+=vis[*it];
vis[*it]=0;
}
}
ans+=vis[x];
s[x].clear();
vis[x]=0;//重置点x的状态
}
cout<<ans<<endl;
}
return 0;
}