連接:https://www.nowcoder.com/acm/contest/84/C 來源:牛客網 題目描述 平面上有若干個點,從每一個點出發,你能夠往東南西北任意方向走,直到碰到另外一個點,而後才能夠改變方向。 請問至少須要加多少個點,使得點對之間互相能夠到達。 輸入描述: 第一行一個整數n表示點數( 1 <= n <= 100)。 第二行n行,每行兩個整數xi, yi表示座標( 1 <= xi, yi <= 1000)。 y軸正方向爲北,x軸正方形爲東。 輸出描述: 輸出一個整數表示最少須要加的點的數目。 示例1 輸入 2 2 1 1 2 輸出 1 示例2 輸入 2 2 1 4 1 輸出 0
【分析】:ios
若兩個點橫座標或者縱座標相同,兩點間連一條邊,經過dfs統計連通塊的個數。spa
固然並查集也是能夠的,但因爲不涉及給出任意兩個點判斷是否連通,所以dfs更輕便。code
【出處】: CodeForces 217A Ice Skatingci
【代碼】:get
/* 將行相同或列相同的點合併爲一棵樹,最後看有多少棵樹便可計算還需多少個點。 */ #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int father[1001]; int find(int x) { if(father[x]==x) return x; else { father[x]=find(father[x]); return father[x]; } } void merge(int a,int b) { int fa=find(a); int fb=find(b); if(fa!=fb) { father[fb]=fa; } } int main() { int n; while(cin>>n&&n) { int x[n+1],y[n+1],ans=0; for(int i=1;i<=n;i++) father[i]=i; for(int i=1;i<=n;i++) { cin>>x[i]>>y[i]; } for(int i=1;i<n;i++) { for(int j=i+1;j<=n;j++) { if(x[i]==x[j]||y[i]==y[j]) { merge(i,j); } } } for(int i=1;i<=n;i++) { if(father[i]==i) ans++; } cout<<ans-1<<endl; } return 0; }