1107 Social Clusters (30point(s)) Easy only once *并查集的问题,需要注意下

基本思想:

主要考察并查集的使用,其中注意节点合并的思想;

 

关键点:

map排序似乎无法进行,可以转成Vector>进行sort排序,条件改写一下就行了;

#include
#include
#include
#include 
#include<string>
#include
#include
#include
#include
#include
using namespace std;

const int maxn = 1010;
vector<int>father;
vector<int>fin;
int course[maxn];
int n;

void init() {
    father.resize(n+1);
    fill(course, course + maxn, 0);
    for (int i = 0; i < father.size(); i++) {
        father[i] = i;
    }
}

bool cmp(int a, int b) {
    return a > b;
}

int findfather(int n) {
    int temp = n;
    while (father[n] != n) {
        n = father[n];
    }
    /*
    while (father[temp] != n) {
        int a = father[temp];
        father[temp] = n;
        temp = a;
    }
    */
    return n;
}

void contain(int a, int b) {
    int aa = findfather(a);
    int bb = findfather(b);
    if (aa != bb) {
        father[aa] = bb;
    }
}

void cnt() {
    map<int, int>m;
    for (int i = 1; i <= n; i++) {
        int f = findfather(i);
        m[f]++;
    }
    cout << m.size() << endl;
    bool flag = true;
    for (auto it = m.begin(); it != m.end();it++) {
        fin.push_back(it->second);
    }
    sort(fin.begin(), fin.end(), cmp);
    for (int i = 0; i < fin.size(); i++) {
        if (i == 0)
            cout << fin[i];
        else
            cout << " " << fin[i];
    }
}

int main() {
    cin >> n;
    int a,b;
    init();
    for (int i = 1; i <= n; i++) {
        scanf("%d: ", &a);
        //cout << a << endl;
        for (int j = 0; j < a; j++) {
            cin >> b;
            if (course[b] == 0) {
                //如果第一次访问添加这个课程;
                course[b] = i;
                //添加课程内的人;
            }
            else {
                //如果不是的第一次;
                contain(i, course[b]);
                //将两个选课相同的人进行合并;
            }
        }
    }
    //构造完成,进行合并;
    cnt();
    return 0;
}

 

你可能感兴趣的:(1107 Social Clusters (30point(s)) Easy only once *并查集的问题,需要注意下)