Codeforces Round #500 (Div. 2) [based on EJOI] D.Chemical table
说在前面
我又不是话痨又不是话匣子又不是不说话会死星人才不需要次次都写一个说在前面吧
真香
Chemical table
Description
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard 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
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
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 1We 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.
题意翻译
有一个r*c的矩阵,矩阵上面有q个化学元素,只要存在三个元素(r1,c1) , (r2,c1) , (r1,c2),其中r1≠r2,c1≠c2,那么在(r2,c2)也会产生一个化学元素。
也就是矩形四角三缺一就会出现第四个
然后周而复始,新出现的化学元素也参加三缺一生四的Game。
当然只靠开始的q个可能是不够的,问开始的时候最少再加几个就能用化学元素填满整个表。
分析
(至少我的)突破口在r和c的范围。
200000肯定二维开不下,最多开一维。
然后就想到了Place the robot,开一个一维数组记录各行,开一个一维数组记录各列。
然后二分图乱整。
乱整试一下。
如果我们把读入的点的坐标的横坐标和纵坐标连一条线,
我们随便找一个三缺一,比如
(3,4)。
我们发现R3和C4中间没有红线,但是却是间接连着的。(R3→C3→R5→C4)
再进行第二轮三缺一生四。
好像走不动了。
我们大概可以猜测只要在右侧二分图中连起来的坐标组合起来的点都会被麻将化学元素占领。
也就是这个绿色的联通块的坐标组合……占领。
那如果要把每个格子都占领,就是要把每个联通块都连接起来。
那么答案就是联通块数量减一。
搞定。
脑子不行了话都不会说了。。。。。
代码
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
void Read(int &p)
{
p=0;
char c=getchar();
while(c<'0' || c>'9')
c=getchar();
while(c>='0' && c<='9')
p=p*10+c-'0',c=getchar();
}
const int MAXN=202018;
int R,C,q,a,b,ans;
vector<int> G[MAXN][2];
int vis[MAXN][2];
void color(int pos,int loc,int Cr)
{
int sz=G[pos][loc].size();
vis[pos][loc]=Cr;
for(int i=0;i<sz;i++)
if(!vis[G[pos][loc][i]][!loc])
vis[G[pos][loc][i]][!loc]=Cr,
color(G[pos][loc][i],!loc,Cr);
}
int main()
{
Read(R); Read(C); Read(q);
while(q--)
Read(a),Read(b),G[a][0].push_back(b),G[b][1].push_back(a);
for(int i=1;i<=R;i++) if(!vis[i][0]) color(i,0,++ans);
for(int i=1;i<=C;i++) if(!vis[i][1]) color(i,1,++ans);
printf("%d\n",ans-1);
}