zoukankan      html  css  js  c++  java
  • [PAT] A1107 Social Clusters

    并查集

    AC代码

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include <cstdio>
    #include <vector>
    #include<algorithm>
    using namespace std;
    #define N 1002
    int isRoot[N] = { 0 }, father[N];
    vector<int>hobbies[N];
    int findFather(int v) {
    	int a = v;
    	while (father[v] != v)v = father[v];
    	while (father[a] != v) {
    		int z = father[a];
    		father[a] = v;
    		a = z;
    	}
    	return v;
    }
    void merge(int a, int b) {
    	int u = findFather(a);
    	int v = findFather(b);
    	if (u != v)father[u] = v;
    }
    bool ifmerge(int a, int b) {
    	int flag = false;
    	for (int i = 0;i < hobbies[a].size();i++)
    		for (int j = 0;j < hobbies[b].size();j++) {
    			if (hobbies[a][i] == hobbies[b][j])flag = true;
    		}
    	return flag;
    }
    bool cmp(int a, int b) {
    	return a > b;
    }
    int main() { 
    	int n, i, j;    
    	scanf("%d", &n); 
    	int thobby, numhobby;
    	for (i = 1;i <= n;i++) {
    		scanf("%d: ", &numhobby);
    		for (j = 0;j < numhobby;j++) {
    			scanf("%d", &thobby);
    			hobbies[i].push_back(thobby);
    		}
    	}
    	for (i = 1;i <= n;i++)
    		father[i] = i;
    	for (i = 1;i < n;i++) {
    		for (j = i + 1;j <= n;j++) {
    			if(ifmerge(i, j))
    				merge(i, j);
    		}
    	}
    	for (i = 1;i <= n;i++)
    		isRoot[findFather(i)]++;
    	int numcluster = 0;
    	for (i = 1;i <= n;i++)
    		if (isRoot[i] != 0)numcluster++;
    	printf("%d
    ", numcluster);
    	sort(isRoot, isRoot + n + 1, cmp);
    	if (isRoot[0] != 0)printf("%d", isRoot[0]);
    	i = 1;
    	while (isRoot[i] != 0) {
    		printf(" %d", isRoot[i]);
    		i++;
    	}
    	return 0; 
    }
    
    

    对比柳神的代码,发现爱好不需要用vector数组存起来,可以输入一个处理一个。即:

    用course[t]表示任意一个喜欢t活动的人的编号。

    1. 如果当前的活动t之前没有人喜欢过(course[t]==0),那么就course[t] = i,i为它自己的编号,表示i为喜欢course[t]的一个人的编号。
    2. 如果t之前有人喜欢过了,那么就让i和喜欢这个活动的人(即course[t])处在同一个社交圈里, 即Union(i, findFather(course[t]))。

    代码实现如下:

    for(int i = 1; i <= n; i++) {
        scanf("%d:", &k);
        for(int j = 0; j < k; j++) {
            scanf("%d", &t);
            if(course[t] == 0)
                course[t] = i;
            else Union(i, course[t]);
        }
    }
    
  • 相关阅读:
    .NET Core中的鉴权授权正确方式(.NET5)
    关于调试程序容易忽略的问题
    Activity组件的启动过程
    Service组件应用实例
    Navicat_Premium 支持mac m1芯片
    15种sql优化
    sql语句中with用法
    用传对象方式修改sql
    如何将java project转换成maven项目
    SQLSERVER 快速替换引号字段
  • 原文地址:https://www.cnblogs.com/yue36/p/13322119.html
Copyright © 2011-2022 走看看