This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub hitonanode/cplib-cpp
#define PROBLEM "https://judge.yosupo.jp/problem/maximum_independent_set" #include "../max_weight_independent_set.hpp" #include <iostream> using namespace std; int main() { cin.tie(nullptr), ios::sync_with_stdio(false); int N, M; cin >> N >> M; max_weight_independent_set<int> solver(N); while (M--) { int u, v; cin >> u >> v; solver.add_edge(u, v); } cout << solver.solve() << '\n'; for (int i = 0; i < N; ++i) { if ((solver.solution_set >> i) & 1) cout << i << ' '; } cout << '\n'; }
#line 1 "graph/test/max_weight_independent_set.lc.test.cpp" #define PROBLEM "https://judge.yosupo.jp/problem/maximum_independent_set" #line 2 "graph/max_weight_independent_set.hpp" #include <algorithm> #include <cassert> #include <stack> #include <vector> // Maximum weight independent set // Requirement: n <= 63 // Complexity: exponential, O(1.381^n n) // Reference: https://www.slideshare.net/wata_orz/ss-12131479, p.34 // Verified: https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3519 template <class Weight> struct max_weight_independent_set { int V; // # of vertices std::vector<long long> conn; std::vector<Weight> ws; long long solution_set; // Solution set is saved here: use (1) / not use (0) Weight eval_solution; // optimal value private: long long state; Weight eval_state; long long avail; void mis_dfs() { std::stack<int, std::vector<int>> st; for (bool retry = true; retry;) { // Pruning retry = false; for (int i = 0; i < V; i++) { if (avail & (1LL << i)) { int nb = __builtin_popcountll(avail & conn[i]); if (nb == 0) { st.emplace(i), avail -= 1LL << i, state |= 1LL << i; eval_state += ws[i]; retry = true; } if (nb == 1) { int j = __builtin_ctzll(avail & conn[i]); if (ws[i] >= ws[j]) { st.emplace(i), avail -= 1LL << i, state |= 1LL << i; eval_state += ws[i]; retry = true; st.emplace(j), avail &= ~(1LL << j); } } } } } if (eval_state > eval_solution) eval_solution = eval_state, solution_set = state; int d = -1, n = -1; for (int i = 0; i < V; i++) { if (avail & (1LL << i)) { int c = __builtin_popcountll(avail & conn[i]); if (c > d) d = c, n = i; } } if (d >= 0) { long long nxt = avail & conn[n]; avail -= 1LL << n; mis_dfs(); state |= 1LL << n; eval_state += ws[n]; avail &= ~nxt; mis_dfs(); avail |= nxt; avail |= 1LL << n; state &= ~(1LL << n); eval_state -= ws[n]; } for (; st.size(); st.pop()) { int i = st.top(); avail |= 1LL << i; if ((state >> i) & 1LL) state -= 1LL << i, eval_state -= ws[i]; } } public: max_weight_independent_set(const int V) : V(V), conn(V), ws(V, Weight(1)), solution_set(0), eval_solution(Weight()), state(0), eval_state(Weight()), avail((1LL << V) - 1) {} max_weight_independent_set(const std::vector<Weight> &ws_) : max_weight_independent_set(ws_.size()) { ws = ws_; } void add_edge(int u, int v) { assert(u != v); assert(0 <= u and u < V); assert(0 <= v and v < V); conn[u] |= 1LL << v; conn[v] |= 1LL << u; } Weight solve() { state = 0, eval_state = Weight(), avail = (1LL << V) - 1; solution_set = 0, eval_solution = Weight(); mis_dfs(); return eval_solution; } }; #line 3 "graph/test/max_weight_independent_set.lc.test.cpp" #include <iostream> using namespace std; int main() { cin.tie(nullptr), ios::sync_with_stdio(false); int N, M; cin >> N >> M; max_weight_independent_set<int> solver(N); while (M--) { int u, v; cin >> u >> v; solver.add_edge(u, v); } cout << solver.solve() << '\n'; for (int i = 0; i < N; ++i) { if ((solver.solution_set >> i) & 1) cout << i << ' '; } cout << '\n'; }