Innopolis University scientists continue to investigate the periodic table. There are n·m known elements and they form a periodic table: a rectangle with n rows and m columns. Each element can be described by its coordinates (r, c) (1 ≤ r ≤ n, 1 ≤ c ≤ m) in the table.
Recently scientists discovered that for every four different elements in this table that form a rectangle with sides parallel to the sides of the table, if they have samples of three of the four elements, they can produce a sample of the fourth element using nuclear fusion. So if we have elements in positions (r1, c1), (r1, c2), (r2, c1), where r1 ≠ r2 and c1 ≠ c2, then we can produce element (r2, c2).
Samples used in fusion are not wasted and can be used again in future fusions. Newly crafted elements also can be used in future fusions.
Innopolis University scientists already have samples of q elements. They want to obtain samples of all n·m elements. To achieve that, they will purchase some samples from other laboratories and then produce all remaining elements using an arbitrary number of nuclear fusions in some order. Help them to find the minimal number of elements they need to purchase.
Input
The first line contains three integers n, m, q (1 ≤ n, m ≤ 200 000; 0 ≤ q ≤ min(n·m, 200 000)), the chemical table dimensions and the number of elements scientists already have.
The following q lines contain two integers ri, ci (1 ≤ ri ≤ n, 1 ≤ ci ≤ m), each describes an element that scientists already have. All elements in the input are different.
Output
Print the minimal number of elements to be purchased.
Examples
Input
2 2 3
1 2
2 2
2 1
Output
0
Input
1 5 3
1 3
1 1
1 5
Output
2
Input
4 3 6
1 2
1 3
2 2
2 3
3 1
3 3
Output
1
题意:现在有一个n*m的方格,有q个方格是已经涂好色了,并且方格有自动涂色功能,如果一个矩形的三个角被涂上颜色了,那么第四个角就被自动涂上颜色。 问最少需要手动涂几个点。
思路:我们有3个点(x1,y1),(x2,y1),(x2,y2),我们就可以生成(x1,y2)。我们可以用并查集维护这种关系,我们合并x1-y1,x2-y1,x2-y2,则x1,x2,y1,y2在一个集合里,则(x1,y2)也存在了。我们只需要最后查询有几个集合,集合个数-1就是答案个数。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
int pre[400009],book[400009];
int find1(int x)
{
if(pre[x]!=x)
pre[x]=find1(pre[x]);
return pre[x];
}
void union1(int x,int y)
{
int fx=find1(x),fy=find1(y);
if(fx!=fy)
pre[fx]=fy;
}
int main()
{
int n,m,q,x,y;
ll res;
res=0;
cin>>n>>m>>q;
for(int i=1;i<=m+n;i++)
pre[i]=i;
memset(book,0,sizeof(book));
for(int i=1;i<=q;i++)
{
cin>>x>>y;
y+=n;
union1(x,y);
}
for(int i=1;i<=m+n;i++)
{
int tmp=find1(i);
if(!book[tmp])
{
res++;
book[tmp]=1;
}
}
cout<<res-1<<endl;
return 0;
}