zoukankan      html  css  js  c++  java
  • poj_1161 并查集

    题目大意

        一个学校里面有n个学生(标号从0到n-1)和m个社团(标号从0到m-1),每个学生属于0个或多个社团。近期有SARS传播,属于同一个社团的学生的SARS可以相互传染。给出m个社团中的学生标号,已知学生0被传染了SARS,求所有可能被传染SARS的人数。

    题目分析

        典型的集合操作,求集合的大小。可以使用并查集来实现。学生0属于的所有社团中的所有学生都可能被传染,而这些所有和学生0属于相同社团的学生属于的所有社团的所有学生都可能被传染,如此递推下去,可以知道所有可能被传染的学生总数。(注意这里的“集合”并不是指“社团”) 
        若学生s被传染,则将s加入到被传染的集合,同时将s属于的所有社团m中的所有学生加入到被传染的集合。假设这些学生本来有自己属于的集合k,这个操作相当于,将这些学生所属的所有集合进行合并。即需要将同一个社团的所有人的集合进行合并。 
        于是,可以在开始的时候设置每个学生单独属于自己的集合(即i = par[i]),在每次输入一个社团的时候,将该社团内的成员的集合进行合并。同时,需要维护每个集合内的成员数量的信息,这样在合并的时候需要更新。最后,求出学生0所属的集合的成员数量即可。

    实现(c++)

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #define MAX_STUDENT_NUM 30001
    int gPar[MAX_STUDENT_NUM];			//每个学生属于的集合id
    int gGroupNum[MAX_STUDENT_NUM];		//集合中的成员数量
    
    //得到树的根
    int GetPar(int c){
    	if (c != gPar[c]){
    		gPar[c] = GetPar(gPar[c]);
    	}
    	return gPar[c];
    }
    
    //将两个成员所在的集合进行合并
    void Union(int a, int b){
    	int p1 = GetPar(a);
    	int p2 = GetPar(b);
    	if (p1 != p2){
    		gPar[p1] = p2;
    		gGroupNum[p2] += gGroupNum[p1];
    	}
    }
    
    //初始化集合
    void InitGroup(int n){
    	for (int i = 0; i < n; i++){
    		gPar[i] = i;
    		gGroupNum[i] = 1;
    	}
    }
    
    int main(){
    	int n, m, k, member, member0;
    	while (true){
    		scanf("%d %d", &n, &m);
    		if (n == 0)
    			break;
    		InitGroup(n);
    		for (int i = 0; i < m; i++){
    			scanf("%d %d", &k, &member0);
    			for (int j = 1; j < k; j++){
    				scanf("%d", &member);
    				Union(member, member0);
    			}
    		}
    		int p = GetPar(0);
    		printf("%d
    ", gGroupNum[p]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    转:wcf大文件传输解决之道(1)
    转:WCF传送二进制流数据基本实现步骤详解
    创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址
    创建一个简单的WCF程序
    转:【专题十二】实现一个简单的FTP服务器
    转:【专题十一】实现一个基于FTP协议的程序——文件上传下载器
    转:【专题十】实现简单的邮件收发器
    转:【专题九】实现类似QQ的即时通信程序
    转:【专题八】P2P编程
    转:【专题七】UDP编程补充——UDP广播程序的实现
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4798077.html
Copyright © 2011-2022 走看看