连接: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; }