CF #500 D. Chemical table

http://codeforces.com/contest/1013/problem/D

D. Chemical table

time limit per test

1 second

memory limit per test

512 megabytes

input

standard input

output

standard output

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

Copy

2 2 3
1 2
2 2
2 1

Output

Copy

0

Input

Copy

1 5 3
1 3
1 1
1 5

Output

Copy

2

Input

Copy

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

Output

Copy

1

Note

For each example you have a picture which illustrates it.

The first picture for each example describes the initial set of element samples available. Black crosses represent elements available in the lab initially.

The second picture describes how remaining samples can be obtained. Red dashed circles denote elements that should be purchased from other labs (the optimal solution should minimize the number of red circles). Blue dashed circles are elements that can be produced with nuclear fusion. They are numbered in order in which they can be produced.

Test 1

We can use nuclear fusion and get the element from three other samples, so we don't need to purchase anything.

Test 2

We cannot use any nuclear fusion at all as there is only one row, so we have to purchase all missing elements.

Test 3

There are several possible solutions. One of them is illustrated below.

Note that after purchasing one element marked as red it's still not possible to immidiately produce the middle element in the bottom row (marked as 4). So we produce the element in the left-top corner first (marked as 1), and then use it in future fusions.

题解:转自https://blog.csdn.net/sunyutian1998/article/details/81380663

如果整个矩形的四个边界中有相邻两个已填满 那剩下每个位置都可以被标示

比如这张图 有了左图的三个元素 右图上四个位置都可以三缺一的互相表示 对其他元素造成的影响等价于(r2,1) (r1,1) (1,c1) (1,c2)这四个边界位置

关键是怎么把已给的q个元素换到边界上去 就想到这了.. 没想到用并查集搞.. 出现一个元素就把行列合并 这样出现如左图的三个元素后 对应的两行两列就都被合并在一起 然后等效到对应行列上 并且如果三个元素以(1,1) (2,2) (3,1)这样的位置出现后 对应的三行三列并不会被合并 需等待(1,2) (2,1) (3,2)这样的位置出现后才会被合并在一起 然后等效到边界

最后看有几个集合 也就是还需要几个连接点

注意路径压缩

AC代码

#include <iostream>
#include<bits/stdc++.h>
using namespace std;

#define maxn 400007
int father[maxn];

int find(int n)
{
    if(father[n]==n)
        return n;
    else
    {
        father[n]=find(father[n]);
        return find(father[n]);
    }
}

void Merge(int a,int b)
{
    a=find(a);
    b=find(b);
    if(a!=b)
        father[a]=b;
}

int main()
{
    std::ios::sync_with_stdio(false);
    int n,m,q;
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n+m;++i)
        father[i]=i;
    while(q--)
    {
        int r,c;
        scanf("%d%d",&r,&c);
        Merge(r,c+n);
    }
    int ans=0;
    for(int i=1;i<=n+m;++i)
        if(father[i]==i)
            ans++;
    printf("%d\n",ans-1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36921652/article/details/81667638