原題接続:
質問が意図される:に\(N \回M \)第四のコーナーピースが存在する場合、三角形は自動的にボードを生成することを特徴と長方形の板のいずれかが任意の4点で構成されているためボードは、我々は、少なくともシーク全体ピースをカバーチェス盤リガにどのように多くの作品へ
アイデア:最初は、解決する方法を考えることは容易ではありません正直に言うと。2点の存在は、それが新しい作品を起動するために断念することができ、エンドピースで、あり、そして最終的に作品は、少なくとも作る市松模様がアップ終了まで行うことができますか。
まず形成する4つの片3個の間の関係を分析することができる:三点が与えられる\((X_1、Y_1)\) \((X_1、Y_2)\) \((X_2、Y_1)\)最初に導入することができます三枚\((X_2、Y_2)\) 、我々は、2つの点が他側の一の側に接続されていることを知っているが、固定矩形た\(X \)または\(Y \)は、座標
その選択は、接続関係のランクを通過します。\((X_1、Y_1)\ ) すなわち\(X_1 \)接続\(Y_1を\)で\((X_1、Y_2)\ ) そこに、すなわち\(X_1 \)接続\(Y_2 \)ので(\ X_1、Y_1、Y_2 \)の三点を決定しました。二分前に行うのであれば、これは、より良い接続関係になると思います。我々は、各ラインが添字で表され、各カラムは添字によって表される図2のマトリクスコンバータにこれを置きます。すべての私たちのポイントは、あなたが表現すべてのランクを接続したいの完全二部グラフのノードがあると述べている必要があります。ここでは、セットをマージするために、接続のランクとの関係を互いに素セットを使用することができます。
コード:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
int pre[maxn<<1];
int n,m,q;
int find(int x){
return x==pre[x]?x:pre[x]=find(pre[x]);
}
bool unite(int x,int y){
int fx,fy;
fx = find(x),fy = find(y);
if(fx!=fy){ pre[fx]=fy;return true;}
return false;
}
int main(){
while(cin>>n>>m>>q){
for(int i=0;i<=n+m;i++){
pre[i] = i;
}
int ans = n+m-1;
for(int i=0;i<q;i++){
int x,y;
cin>>x>>y;
if(unite(x,y+n)) ans--;
}
printf("%d\n",ans);
}
}