Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <set>
- #include <stdlib.h>
- #include <algorithm>
- #include <iostream>
- #include <iterator>
- #include <vector>
- #include <set>
- #include <string>
- #include <fstream>
- using namespace std;
- ifstream in("input.txt");
- ofstream out("output.txt");
- struct node {
- string person;
- set<node*> friends;
- node(string p_) : person(p_) {};
- node(string p_, set<node*> f_) : person(p_), friends(f_) {};
- void print() {
- cout << person << " (" << this << ") knows: { ";
- for (auto f : friends)
- cout << f->person << " ";
- cout << "}\n";
- }
- };
- class graph {
- private:
- set<node*> g;
- public:
- void addNode(string p_) {
- node* n = new node(p_);
- g.insert(n);
- }
- void addEdge(string p1_, string p2_) {
- node* n1 = NULL, * n2 = NULL;
- for (auto p : g) {
- if (p->person == p1_) { n1 = p; }
- else if (p->person == p2_) { n2 = p; }
- }
- if (n1 && n2)
- n1->friends.insert(n2), n2->friends.insert(n1);
- }
- set<node*> getUniverse() {
- return g;
- }
- void print() {
- for (auto p : g)
- (*p).print();
- }
- };
- vector<int> sm;
- vector<string> ans;
- int maxi = 0;
- void set_print(set<node*> s) {
- int sum = 0;
- for (auto p : s) {
- sum += sm[stoi(p->person) - 1];
- }
- if (sum > maxi) {
- ans.clear();
- for (auto p : s)
- ans.push_back(p->person);
- out << ans.size() << endl;
- for (auto t : ans) {
- out << t << " ";
- }
- out << endl;
- maxi = sum;
- }
- }
- set<node*> set_union(set<node*> a, set<node*> b) {
- set<node*> c;
- set_union(a.begin(), a.end(), b.begin(), b.end(), inserter(c, c.end()));
- return c;
- }
- set<node*> set_intersection(set<node*> a, set<node*> b) {
- set<node*> c;
- set_intersection(a.begin(), a.end(), b.begin(), b.end(), inserter(c, c.end()));
- return c;
- }
- //note, set_difference is the relative compliment on input set a//
- set<node*> set_difference(set<node*> a, set<node*> b) {
- set<node*> c;
- set_difference(a.begin(), a.end(), b.begin(), b.end(), inserter(c, c.end()));
- return c;
- }
- void bronKerbosch(set<node*> R, set<node*> P, set<node*> X) {
- if (P.empty() && X.empty()) {
- set_print(R);
- }
- set<node*>::iterator v = P.begin();
- while (!P.empty() && v != P.end()) {
- set<node*> singleton = { (*v) };
- bronKerbosch(set_union(R, singleton), set_intersection(P, (*v)->friends), set_intersection(X, (*v)->friends));
- P = set_difference(P, singleton);
- X = set_union(X, singleton);
- if (!P.empty())
- v = P.begin();
- }
- }
- int main() {
- int tt;
- in >> tt;
- while (tt--) {
- graph g;
- int n, m;
- in >> n >> m;
- sm.clear();
- sm.resize(m);
- for (int i = 0; i < m; ++i) {
- g.addNode(to_string(i + 1));
- }
- vector<vector<int>> z(m);
- for (int i = 0; i < m; ++i) {
- int k;
- in >> k;
- sm[i] = k;
- for (int j = 0; j < k; ++j) {
- int x;
- in >> x;
- z[i].push_back(x);
- }
- }
- for (int i = 0; i < m; ++i) {
- for (int j = 0; j < m; ++j) {
- bool flag = true;
- if (i != j) {
- vector<int> c(n + 1, 0);
- for (int k : z[i]) {
- c[k]++;
- }
- for (int k : z[j]) {
- c[k]++;
- }
- for (int k = 0; k < n + 1; ++k) {
- if (c[k] > 1)
- flag = false;
- }
- if (flag) {
- g.addEdge(to_string(i + 1), to_string(j + 1));
- }
- }
- }
- }
- set<node*> R, P, X;
- P = g.getUniverse();
- maxi = 0;
- bronKerbosch(R, P, X);
- out << ans.size() << endl;
- for (auto t : ans) {
- out << t << " ";
- }
- out << endl;
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment