http://codeforces.com/problemset/problem/1013/D
如果整个矩形的四个边界中有相邻两个已填满 那剩下每个位置都可以被标示
比如这张图 有了左图的三个元素 右图上四个位置都可以三缺一的互相表示 对其他元素造成的影响等价于(r2,1) (r1,1) (1,c1) (1,c2)这四个边界位置
关键是怎么把已给的q个元素换到边界上去 就想到这了.. 没想到用并查集搞.. 出现一个元素就把行列合并 这样出现如左图的三个元素后 对应的两行两列就都被合并在一起 然后等效到对应行列上 并且如果三个元素以(1,1) (2,2) (3,1)这样的位置出现后 对应的三行三列并不会被合并 需等待(1,2) (2,1) (3,2)这样的位置出现后才会被合并在一起 然后等效到边界
最后看有几个集合 也就是还需要几个连接点
#include <bits/stdc++.h>
using namespace std;
int f[400010];
int n,m,q;
int getf(int p)
{
if(f[p]==p) return p;
else
{
f[p]=getf(f[p]);
return f[p];
}
}
void unite(int u,int v)
{
int fu,fv;
fu=getf(u);
fv=getf(v);
f[fv]=fu;
}
int main()
{
int i,x,y,ans;
scanf("%d%d%d",&n,&m,&q);
for(i=1;i<=n+m;i++) f[i]=i;
while(q--)
{
scanf("%d%d",&x,&y);
unite(x,n+y);
}
ans=0;
for(i=1;i<=n+m;i++)
{
if(f[i]==i) ans++;
}
printf("%d\n",ans-1);
return 0;
}