並查集在實際問題中的應用
並查集:用以將元素高效分組以及區分。
題目來源: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並查集
- 並查集深度應用並查集
- 並查集的簡單應用並查集
- 並查集(二)並查集的演算法應用案例上並查集演算法
- 關於並查集問題並查集
- Linux在實際中的應用Linux
- 並查集擴充套件應用並查集套件
- Vue合理配置axios並在專案中進行實際應用?VueiOS
- 並查集(一)並查集的幾種實現並查集
- 【學習筆記】並查集應用筆記並查集
- 並查集經典應用場景並查集
- 策略模式在業務中的實際應用模式
- 策略模式在實際業務中的應用模式
- week2 kuangbin 題單 最短路問題 + 並查集問題並查集
- 好用的Vue狀態管理模式:淺談Vuet在實際應用中解決的問題Vue模式
- 【帶權並查集】理論和應用並查集
- 使用並查集處理集合的合併和查詢問題並查集
- 並查集演算法Union-Find的思想、實現以及應用並查集演算法
- 在實際應用中聯合體union的妙用
- 策略模式解析以及在Android中的實際應用模式Android
- Nuxt配合Node在實際生產中的應用UX
- 並查集題目合集並查集
- Google Guava 在實際場景中的應用封裝GoGuava封裝
- 面試常考演算法題之並查集問題面試演算法並查集
- 【並查集】【帶偏移的並查集】食物鏈並查集
- 並查集java實現並查集Java
- 並查集-Java實現並查集Java
- 專題五 並查集【Kuangbin】並查集
- sklearn中的pipeline實際應用
- 並查集到帶權並查集並查集
- [Elasticsearch] ES 的Mapping 設計在實際場景中應用ElasticsearchAPP
- 機器學習實際應用中必須考慮到的9個問題機器學習
- 理解笛卡爾積在資料庫查詢中的實際應用與最佳化資料庫
- 簡單易懂的並查集演算法以及並查集實戰演練並查集演算法
- 實際專案中遇到的問題
- 消除假確定性並解決實際問題
- 結構struct(值型別)在實際應用中應該注意的點Struct型別