题目大意:维护一张弦图,支持加边、删边和询问图中有多少个联通块
题解:这是smg……Orz
我的收获:利用询问较少的特性……
#include <map>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 5050
using namespace std;
int n,m,q;
map<pair<int,int>,bool> edges;
struct Query{
int type,x,y;
//1-A 2-D 3-Q
friend istream& operator >> (istream &_,Query &q)
{
char p[10];
scanf("%s",p);
if(p[0]=='A')
q.type=1,scanf("%d%d",&q.x,&q.y);
else if(p[0]=='D')
{
q.type=2;
scanf("%d%d",&q.x,&q.y);
if( edges.find( make_pair(q.x,q.y) )!=edges.end() )
edges[make_pair(q.x,q.y)]=true;
else if( edges.find( make_pair(q.y,q.x) )!=edges.end() )
edges[make_pair(q.y,q.x)]=true;
}
else
q.type=3;
return _;
}
}queries[10100];
vector<int> g[M];
namespace Union_Find_Set{
int fa[M],size[M];
int Find(int x)
{
if(!fa[x])
fa[x]=x,size[x]=1;
if(fa[x]==x)
return fa[x]=x;
return fa[x]=Find(fa[x]);
}
void Union(int x,int y)
{
x=Find(x);y=Find(y);
if(x==y) return ;
if(size[x]>size[y])
swap(x,y);
fa[x]=y;size[y]+=size[x];
}
}
using namespace Union_Find_Set;
int v[M],T;
void DFS(int x)
{
vector<int>::iterator it;
v[x]=T;
for(it=g[x].begin();it!=g[x].end();it++)
if(v[*it]!=T)
DFS(*it);
}
int Get_Ans()
{
int i,re=0;++T;
for(i=1;i<=n;i++)
if(Find(i)==i&&v[i]!=T)
++re,DFS(i);
return re;
}
int main()
{
int i,x,y;
cin>>n>>m;
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
edges[make_pair(x,y)]=false;
}
cin>>q;
for(i=1;i<=q;i++)
cin>>queries[i];
map<pair<int,int>,bool>::iterator it;
for(it=edges.begin();it!=edges.end();it++)
{
x=Find(it->first.first);
y=Find(it->first.second);
if(!it->second)
Union(x,y);
}
for(it=edges.begin();it!=edges.end();it++)
{
x=Find(it->first.first);
y=Find(it->first.second);
if(it->second)
g[x].push_back(y),g[y].push_back(x);
}
for(i=1;i<=q;i++)
{
if(queries[i].type==1)
{
x=Find(queries[i].x);y=Find(queries[i].y);
g[x].push_back(y);g[y].push_back(x);
}
else if(queries[i].type==2)
{
x=Find(queries[i].x);y=Find(queries[i].y);
vector<int>::iterator it;
for(it=g[x].begin();it!=g[x].end();it++)
if(*it==y)
{
g[x].erase(it);
break;
}
for(it=g[y].begin();it!=g[y].end();it++)
if(*it==x)
{
g[y].erase(it);
break;
}
}
else
printf("%d\n",Get_Ans());
}
return 0;
}