找出无向图中的各个子图

1.题目:

输入:map<int,set> mp;
key是集合主键,value是集合元素
mp[1]={1,2,3};
mp[2]={1,3,5};
mp[3]={2,6,7};
mp[4]={1,2,7};
mp[5]={11,12,13};
mp[6]={11,12,13};
mp[7]={21,22,23};

输出:最大连通子图序列
[1,2,3,4],[5,6],[7]

2.解决一:

#include <iostream>
#include<algorithm>
#include <vector>
#include <stack>
#include <set>
#include <map>
using namespace std;

using PIV = pair<int, vector<int>>;
vector<PIV> tree;

int find(int val) {
    int root = val;
    while (root != tree[root].first) {
        root = tree[root].first;
    }
    while (root != val) { 
        val = tree[val].first;
        tree[val].first = root;
    } //路径压缩
    return val;
}

void merge(int a, int b) {
    int roota = find(a);
    int rootb = find(b);
    tree[roota].first = rootb;
}

int main() {
    tree.resize(23 + 1);
    for (int i = 0; i < tree.size(); ++i) {
        tree[i] = { i, {} };
    }

    map<int, vector<int>> mp;
    mp[1] = { 1,2,3 };
    mp[2] = { 1,3,5 };
    mp[3] = { 2,6,7 };
    mp[4] = { 1,2,7 };
    mp[5] = { 11,12,13 };
    mp[6] = { 11,12,13 };
    mp[7] = { 21,22,23 };

    for (auto& kv : mp) {
        vector<int>& temp = kv.second;
        if (temp.size() == 0) continue;
        tree[temp[0]].second.emplace_back(kv.first);
        for (int i = 1; i < temp.size(); ++i) {
            tree[temp[i]].second.emplace_back(kv.first);
            merge(temp[i - 1], temp[i]);
        }
    }

    map<int, set<int>> ans;
    for (auto& ele : tree) {
        if (ele.second.size())
            ans[find(ele.first)].insert(ele.second.begin(), ele.second.end());
    }

}

3.解决二:

#include <iostream>
#include<algorithm>
#include <vector>
#include <stack>
#include <set>
#include <map>
using namespace std;

using PIS = pair<int, set<int>>;
unordered_map<int, PIS> tree;

int find(int val) {
    if (tree.find(val) == tree.end()) {
        //tree[val] = {};
    }
    else {
        int root = val;
        while (root != tree[root].first) {
            root = tree[root].first;
        }
        while (root != val) {
            val = tree[val].first;
            tree[val].first = root;
        } //路径压缩
    }
    return val;
}

void merge(int a, int b) {
    int roota = find(a);
    int rootb = find(b);
    tree[roota].first = rootb;
}

int main() {
    map<int, vector<int>> mp;
    mp[1] = { 1,2,3 };
    mp[2] = { 1,3,5 };
    mp[3] = { 2,6,7 };
    mp[4] = { 1,2,7 };
    mp[5] = { 11,12,13 };
    mp[6] = { 11,12,13 };
    mp[7] = { 21,22,23 };

    for (auto& kv : mp) {
        vector<int>& temp = kv.second;
        if (temp.size() == 0) continue;
        tree[temp[0]].second.insert(kv.first);
        if (tree[temp[0]].first == 0)tree[temp[0]].first = temp[0];
        for (int i = 1; i < temp.size(); ++i) {
            tree[temp[i]].second.insert(kv.first);
            if (tree[temp[i]].first == 0)tree[temp[i]].first = temp[i];
            merge(temp[i - 1], temp[i]);
        }
    }

    map<int, set<int>> ans;
    for (auto& ele : tree) {
        //if (ele.second.second.size())
            ans[find(ele.second.first)].insert(ele.second.second.begin(), ele.second.second.end());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值