1. 程式人生 > >並查集---------kuangbin帶你飛合集

並查集---------kuangbin帶你飛合集

其他 sin har 關系 con bin poj2236 分享圖片 聯通

並查集的一個很重要的特性是傳遞性,如可以從a可以到b,從b可以到c,那麽從a可以到c,如果滿足這個的條件,要求一些特定的集合判定,屬於那些集合,大多都屬於並查集

poj2236

題意很簡明::::

在一次地震中有n臺電腦被損壞了,然後給出這n臺電腦的坐標!

隨後給出多組詢問,以0開頭就表示修理好這臺電腦,如果是s就表示求兩臺電腦之間能否通訊

通訊的條件是兩臺電腦距離小於等於d且具有傳遞性 如a能和b通信,b能和c通信,然後a便能和c通信

一個要註意的一點是給出的歐幾裏得距離,但是這些坐標都是整數,所以可以用他們的平方來表示(而且最重要的一點是他們的平方並不大,以後碰到這種題目也可以朝這方面去想,因為這樣可以保證不會出現精度問題,前提是不會爆long long)

從那個傳遞性來看的話可以考慮並查集(並查集是看一些元素是不是在一個聯通分量裏面的,而傳遞性正是聯通分量的一種特性),但是沒輸入一臺電腦,怎麽把它維護與其他的關系呢

這樣就只能暴力了,一開始一直沒看時間復雜度,導致沒敢暴力,這是問題啊。

以後看題一定是看出問題的模型,問題的本質,分析一下數據,然後看一下時空復雜度,而且還要對證一下樣例,最後對證一些特值,

下面給出代碼

技術分享圖片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5
using namespace std; 6 const int maxn=1100; 7 int n,d; 8 struct point{ 9 int x,y; 10 }; 11 point pt[2010]; 12 char cr; 13 int a,b; 14 int f[2010]; 15 int vis[2010]; 16 17 int find(int k){ 18 if(f[k]==-1) return k; 19 else return f[k]=find(f[k]); 20 } 21 22 bool join(int s,int e){ 23 return
(pt[s].x-pt[e].x)*(pt[s].x-pt[e].x)+(pt[s].y-pt[e].y)*(pt[s].y-pt[e].y)<=d*d; 24 } 25 26 int main(){ 27 scanf("%d%d",&n,&d); 28 for(int i=1;i<=n;i++) scanf("%d%d",&pt[i].x,&pt[i].y); 29 for(int i=1;i<=n;i++) f[i]=-1; 30 memset(vis,0,sizeof(vis)); 31 while(scanf("\n%c",&cr)!=EOF){ 32 if(cr==S){ 33 scanf("%d%d",&a,&b); 34 int t1=find(a),t2=find(b); 35 if(t1!=t2) printf("FAIL\n"); 36 else printf("SUCCESS\n"); 37 }else{ 38 scanf("%d",&a); 39 vis[a]=1; 40 for(int i=1;i<=n;i++){ 41 if(vis[i]==1&&i!=a){ 42 int t1=find(i),t2=find(a); 43 if(t1==t2) continue; 44 if(join(i,a)) f[t1]=t2; 45 } 46 } 47 } 48 } 49 return 0; 50 }
View Code

並查集---------kuangbin帶你飛合集