L3-003 社交集群 (30分)(两种思路)

当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。

输入格式:
输入在第一行给出一个正整数 N(≤1000),为社交网络平台注册的所有用户的人数。于是这些人从 1 到 N 编号。随后 N 行,每行按以下格式给出一个人的兴趣爱好列表:

K​i​​ : h​i​​ [1] h​i​​ [2] … h​i​​ [K​i​​ ]其中K​i​​ (>0)是兴趣爱好的个数,h​i​​ [j]是第j个兴趣爱好的编号,为区间 [1, 1000] 内的整数。

输出格式:
首先在一行中输出不同的社交集群的个数。随后第二行按非增序输出每个集群中的人数。数字间以一个空格分隔,行末不得有多余空格。

输入样例:

8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4

输出样例:

3
4 3 1

非并查集版本,20分代码,找不出哪里错了
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

bool vis[1001] = {
    
    false};

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

int main() {
    
    
    int n, k, id, cnt = 0;
    char ch;
    cin >> n;
    int a[n + 1] = {
    
    0};
    vector<int> v[n + 1];
    for (int i = 1; i <= n; i++) {
    
    
        cin >> k >> ch;
        bool flag = true;
        vector<int> vv;
        while (k--) {
    
    
            cin >> id;
            vv.push_back(id);
            if (vis[id]) {
    
    
                flag = false;
                bool x = false;
                for (int j = 1; j <= i - 1; j++) {
    
    
                    for (int p = 0; p < v[j].size(); p++) {
    
    
                        if (id == v[j][p]) {
    
    
                            a[j]++;
                            x = true;
                            break;
                        }
                    }
                    if (x)
                        break;
                }
            }
        }
        if (flag) {
    
    
            for (int x = 0; x < vv.size(); x++) {
    
    
                vis[vv[x]] = true;
                v[i].push_back(vv[x]);
            }
            cnt++;
            a[i]++;
        }
    }
    cout << cnt << endl;
    bool judge = true;
    sort(a + 1, a + n + 1, cmp);
    for (int i = 1; i <= n; i++) {
    
    
        if (a[i]) {
    
    
            if (judge) {
    
    
                cout << a[i];
                judge = false;
            } else {
    
    
                cout << " " << a[i];
            }
        } else {
    
    
            break;
        }
    }
    return 0;
}
并查集版本,30分,想到了并查集,但没有用一开始,用并查集写的也出了问题,因为没有想到怎么合并
#include <algorithm>
#include <iostream>
using namespace std;

int f[1001];
int flag[1001];
int num[2002];
int n;

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

void init() {
    
    
    for (int i = 1; i <= n; i++) {
    
    
        f[i] = i;
    }
}

int find(int x) {
    
    
    if (x == f[x])
        return x;
    return f[x] = find(f[x]);
}

void merge(int x, int y) {
    
    
    int a = find(x);
    int b = find(y);
    if (a != b)
        f[b] = a;
}

int main() {
    
    
    cin >> n;
    init();
    int k, id;
    char ch;
    for (int i = 1; i <= n; i++) {
    
    
        cin >> k >> ch;
        for (int j = 0; j < k; j++) {
    
    
            cin >> id;
            if (!flag[id])
                flag[id] = i;
            else
                merge(i, flag[id]);
        }
    }
    for (int i = 1; i <= n; i++) {
    
    
        int x = find(i);
        num[x]++;
    }
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
    
    
        if (num[i])
            cnt++;
    }
    cout << cnt << endl;
    sort(num + 1, num + n + 1, cmp);
    cout << num[1];
    for (int i = 2; i <= n; i++) {
    
    
        if (num[i])
            cout << " " << num[i];
        else
            break;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45845039/article/details/112606777
今日推荐