# 2017.07.08【NOIP提高组】模拟赛B组 连通块(connect) 题解

## 原题：

http://172.16.0.132/senior/#contest/show/2041/1

k行，每行一个整数。

6 5
1 2
5 4
2 3
3 1
3 6
6
1 3
2 5
1 5
5 5
2 4
3 3

4
5
6
3
4
2

## 实现：

``````#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

int x,y,ans,k,xx,yy,n,m,i,f[10001][501],g[10001][501],mg[501],mk[501],a[10001][3];
int getf(int x,int i){return f[i][x]==x?x:(f[i][x]=getf(f[i][x],i));}
int getg(int x,int i){return g[i][x]==x?x:(g[i][x]=getg(g[i][x],i));}
int get(int x){ return mg[x]==x?x:(mg[x]=get(mg[x]));}
int main()
{
freopen("connect.in","r",stdin);freopen("connect.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++) scanf("%d%d",&a[i][1],&a[i][2]);
for(i=1;i<=n;i++) f[0][i]=i,g[m+1][i]=i;
for(i=1;i<=m;i++)
{
memcpy(f[i],f[i-1],sizeof(f[i]));
xx=getf(a[i][1],i);
yy=getf(a[i][2],i);
if(xx!=yy) f[i][xx]=yy;
}
for(i=m;i>=1;i--)
{
memcpy(g[i],g[i+1],sizeof(g[i]));
xx=getg(a[i][1],i);
yy=getg(a[i][2],i);
if(xx!=yy) g[i][xx]=yy;
}
scanf("%d",&k);
while (k--)
{
scanf("%d%d",&x,&y);
if(x>y) swap(x,y);
ans=0;
memcpy(mg,f[x-1],sizeof(mg));
for(i=1;i<=n;i++)
{
xx=get(mg[i]);
yy=get(g[y+1][i]);
if(xx!=yy) mg[xx]=yy;
}
for(i=1;i<=n;i++)
{
xx=get(mg[i]);
if(mk[xx]!=k) mk[xx]=k,ans++;
}
printf("%d\n",ans);
}
}
``````