并查集
#include <stdio.h> #define MAXSIZE 1000 void init(int, int []); int getf(int); int disjointSetMerge(int,int); int f[MAXSIZE] = {0}; //我也不知道如何把递归函数中不用全局变量 /*先阅读主函数是一个好习惯*/ int main(){ int n; //元素个数 int m; int x,y; int sum=0; scanf("%d %d",&n, &m); init(n,f); for(int i=1;i<=m;i++){ scanf("%d %d", &x,&y); disjointSetMerge(x,y); //两个元素各自所属的集合的合并 } for(int i=1;i<n;i++){ if(f[i]==i) sum++; } printf("%d\n",sum); return 0; } /*数组初始化*/ void init(int n, int f[]){ for(int i=1;i<=n;i++) f[i]=i; return; } /*寻找根节点递归函数*/ int getf(int v){ if(f[v]=v) return v; else { // 路径压缩,提高以后寻找根节点的速度 f[v]=getf(f[v]); return f[v]; } } /*合并两个子集*/ int disjointSetMerge(int v, int u){ int t1,t2; //t1,t2分别为v,u的根节点 t1 = getf(v); t2 = getf(u); if(t1!=t2) { f[t2]=t1; //t2为t1的祖先 return 1; } return 0; }