並查集在實際問題中的應用
並查集:用以將元素高效分組以及區分。
題目來源:codeforces 1012B
原問題如下,在一個(n*m)的table上,element會做出一種增值行為,如果有三個物質處於某個矩形的三個頂點上,那麼在第四個頂點上會自動增值出一個element。現在table上已經存在了一些物質,求出最少仍需多少額外的物質,使得其可以將table覆蓋。
對於解這道題來說,靈活的轉化思想非常重要。首先我們可以證明,如果一個矩形有兩條相鄰的邊被覆蓋滿,這個矩形就可以通過增值自行覆蓋。進一步我們可以發現,如果將這兩條邊按垂直方向“打散”之後分散在矩形中,依然可以完成增值。
這個性質的本質是什麼呢,可以將存在三個點(r1,c1),(r1,c2),(r2,c1),看作在(r1,c1),(r1,c2),(r2,c1)三對值之間存在聯絡,因而r2和c2也發生了聯絡,於是點(r2,c2)也隨之存在,因此可以用並查集來解決問題,全集即為(r1,r2……rn,c1,c2……cn)。
每輸入一個點,即將對應兩個值unite起來;輸入完畢後,會出現若干集合。這些集合內部的橫縱座標值自由組合形成的點就是已存在的;而集合之間所能組合形成的點都是尚未塗色的。最終我們希望達到的效果是,所有值都處在一個集合裡,這樣不論考查哪個點,它的橫縱座標一定是聯絡起來的。因此我們額外塗點的作用實際上,是將不同集合聯絡起來,因此結果等於集合數-1
附AC程式碼
#include<iostream>
#include<cstring>
using namespace std;
int p[400010],r[400010];
int fa(int ch)
{
if(p[ch]==ch)
return ch;
return fa(p[ch]);
}
void unite(int u,int v)
{
int fu=fa(u);
int fv=fa(v);
if(fu!=fv)
{
if(r[fv]==r[fu])
{
r[fu]++;
p[fv]=fu;
}
else if(r[fu]<r[fv])
p[fu]=fv;
else
p[fv]=fu;
}
}
int main()
{
int n,m,q;
cin>>n>>m>>q;
for(int i=1; i<=n+m; i++)
p[i]=i;
for(int i=0; i<q; i++)
{
int r,c;
scanf("%d%d",&r,&c);
unite(r,c+n);
}
int ans=0;
for(int i=1; i<=n+m; i++)
if(p[i]==i)
ans++;
cout<<ans-1<<endl;
return 0;
}
相關文章
- 並查集的應用並查集
- 並查集應用並查集
- 並查集—應用並查集
- 並查集的應用2並查集
- 並查集深度應用並查集
- 並查集以及應用並查集
- 並查集的簡單應用並查集
- 並查集的分析及應用並查集
- 並查集(二)並查集的演算法應用案例上並查集演算法
- MySQL實際應用中遇到的鎖問題薦MySql
- 關於並查集問題並查集
- 並查集應用總結並查集
- Linux在實際中的應用Linux
- 並查集的應用:hdu 1213並查集
- 社交網路 (並查集的應用)並查集
- 並查集詳解與應用並查集
- 並查集擴充套件應用並查集套件
- 策略模式在實際業務中的應用模式
- 策略模式在業務中的實際應用模式
- 食物鏈(並查集的簡單應用)並查集
- 並查集(一)並查集的幾種實現並查集
- 交換技術:反向訪問列表在實際中的應用(轉)
- 並查集經典應用場景並查集
- 【學習筆記】並查集應用筆記並查集
- Vue合理配置axios並在專案中進行實際應用?VueiOS
- Runtime在實際開發中的應用
- 並查集的初級應用及進階並查集
- 好用的Vue狀態管理模式:淺談Vuet在實際應用中解決的問題Vue模式
- 機器學習實際應用中必須考慮到的9個問題機器學習
- 並查集(Union-Find) 應用舉例並查集
- 【帶權並查集】理論和應用並查集
- 並查集 (Union-Find Sets)及其應用並查集
- Nuxt配合Node在實際生產中的應用UX
- JNI解析以及在Android中的實際應用Android
- 資料結構 — 並查集的原理與應用資料結構並查集
- 並查集演算法Union-Find的思想、實現以及應用並查集演算法
- 使用並查集處理集合的合併和查詢問題並查集
- 並查集題目合集並查集