3 solutions

  • 1
    @ 2022-1-16 16:19:37

    采用并查集的思想:我们只需要计算出有几个家族,家族数减一就是答案

    #include <bits/stdc++.h>
    using namespace std;
    int w[1007]; 
    int find(int x){
    	if(w[x]==x) return x;
    	else return w[x]=find(w[x]);
    }
    int main(){
    	int n,m,x,y;
    	while(~scanf("%d%d",&n,&m)&n){
    		for(int i=1;i<=n;i++) w[i]=i;
    		for(int i=0;i<m;i++){
    			scanf("%d%d",&x,&y);
    			w[find(x)]=find(y);
    		}
    		int sum=0;
    		for(int i=1;i<=n;i++){
    			if(i==w[i]) sum++;
    		}
    		cout<<sum-1;
    		printf("\n");
    	}
    }
    
    • 0
      @ 2023-4-5 16:09:36
      #include<bits/stdc++.h>
      using namespace std;
      
      const int N = 1e3+7;
      int nums[N];
      // 使用并查集思想,使用并查集计算出孤立的点n(孤立的点即自己是自己的祖先),答案为n-1
      
      void init(){
          for (int i = 1; i < N; i++) {
              nums[i] = i;
          }
      }
      
      int find(int x) {
          while (x != nums[x]) {
              x = nums[x];
          }
          return x;
      }
      
      void merge(int a, int b){
          int af = find(a);
          int bf = find(b);
          if (af != bf) nums[bf] = af;
      }
      
      
      int main (){
          int n, m;
          while (~ scanf("%d %d", &n, &m) & n) {
              init();
              // 使孤立的点连接起来
              for (int i = 1; i <= m; i++) {
                  int a, b;
                  scanf("%d %d", &a, &b);
                  merge(a, b);
              }
      
              // 计算连接后,一共有n个部分,答案为n-1
              int sum = 0;
              for (int i = 1; i <= n; i++) {
                  if (nums[i] == i) sum++;
              }
              printf("%d\n", sum - 1);
          }
      
      
          return 0;
      }
      
      • 0
        @ 2023-2-1 21:40:57

        并查集模板 需要判断集合数

        #include <bits/stdc++.h>
        using namespace std;
        const int N=1e3+7;
        int fa[N]; 
        int x,y,u,v;
        void init(){//初始化,每个数看成一个集合
        	for(int i=1;i<=N;i++) fa[i]=i;
        }
        int find(int x){   //这里不能用路劲压缩
           if(x==fa[x]) return x;
           else return find(fa[x]); 
        }
        void merge(int x,int y)//合并
        {
        	u=find(x);
        	v=find(y);
        	if(u!=v) fa[u]=v;
        }
        int main(){
        	int n,m,x,y;
        	while(~scanf("%d%d",&n,&m)&n){
        		init();  //注意位置
        		for(int i=0;i<m;i++){
        			scanf("%d%d",&x,&y);
        			 merge(x,y);
        		}
        		int sum=0;
        		for(int i=1;i<=n;i++){ //已经连通的村庄整体算一个集合
        			if(i==fa[i]) sum++;//!!!
        		}
                printf("%d\n",sum-1);//n个集合可以看成n个点,连通至少需要n-1条边
        	}
        }
        
        • 1

        Information

        ID
        1258
        Time
        1000ms
        Memory
        128MiB
        Difficulty
        5
        Tags
        # Submissions
        110
        Accepted
        44
        Uploaded By