传送门
乍一看还以为是可撤销并查集,不过题目有一句重要的话
保证不被忽略的操作1不构成环
说明所有连通块都是一颗树
我们直到树有一个性质, n n n个点, n − 1 n-1 n−1条边
那么我们只需要维护当前有几条边,几个点在树种就好了
怎么维护…emm学到了,这么维护
map<int,set<int> >mp;
直接把 m a p map map当 v e c t o r vector vector用。
#include <bits/stdc++.h>
using namespace std;
map<int,set<int> >mp;
int n,p,e;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int type,l,r; scanf("%d",&type);
if( type==1 )//连接l,r
{
scanf("%d%d",&l,&r);
if( mp[l].empty() ) p++;//增加一个点
if( mp[r].empty() ) p++;//增加一个点
if( mp[l].find(r)==mp[l].end() )//没有这条边
{
e++;
mp[r].insert(l);
mp[l].insert(r);
}
}
else if( type==2 )//删除l,r的边
{
scanf("%d%d",&l,&r);
if( mp[l].find(r)!=mp[l].end() )//存在这条边,那么删掉
{
e--;
mp[l].erase(r);
mp[r].erase(l);
if( mp[l].empty() ) p--;
if( mp[r].empty() ) p--;
}
}
else printf("%d\n",p-e);
}
}