// File: shininglion[P]find_max_independent_set/./mis.cpp
// Function: std::result_of<main::$_1 (value_type<std::vector<Node, std::allocator<Node>>>::type const&)>::type graph::naiveMinCostMIS<std::vector<Node, std::allocator<Node>>, main::$_0, main::$_1>(std::vector<Node, std::allocator<Node>> const&, std::vector<int, std::allocator<int>>&, main::$_0, main::$_1)
auto naiveMinCostMIS(const T& graph, std::vector<int>& is, EdgeExtractor edge_extractor, CostExtractor cost_extractor) -> typename std::result_of<CostExtractor(const typename value_type<T>::type&)>::type
	{
		using namespace std;
		typedef typename value_type<T>::type NodeType;
		typedef typename result_of<CostExtractor(const NodeType&)>::type CostType;

		const int graph_size = distance( begin(graph), end(graph) );
		is.clear();
		CostType total_cost = numeric_limits<CostType>::max();
		
		CostType temp_cost = CostType();
		unordered_set<int> temp_is;
		vector<bool> pick(graph_size, false);
		
		// check legality
		auto is_feasible = [&](const int node) -> bool {
			const auto& edge_list = edge_extractor( graph[node] ); 
			for (auto& edge : edge_list) {
				if (temp_is.find(edge) != temp_is.end()) { return false; }
			}
			return true;
		};
		
		auto pick_node = [&](const int node, function<void (const int)>& find_mic_cost_mis) {
			pick[node] = true;
			temp_is.emplace(node);
			temp_cost += cost_extractor( graph[node] );
			
			find_mic_cost_mis(node);
			
			pick[node] = false;
			temp_is.erase(node);
			temp_cost -= cost_extractor( graph[node] );
		};
		
		// using recursion to find a mis with given starting node
		function<void (const int)> findMicCostMIS = [&](const int node) {
			for (int i = 0; i < graph_size; ++i) {
				if (pick[i]) { continue; }
				if ( !is_feasible(i) ) { continue; }
				pick_node(i, findMicCostMIS);
			}
			
			if ((temp_is.size() > is.size()) || ((temp_is.size() == is.size()) && (temp_cost < total_cost))) {
				is.clear(); is.reserve(temp_is.size());
				for_each(temp_is.cbegin(), temp_is.cend(), [&](int val) { is.push_back(val); } );
				total_cost = temp_cost;
			}
		};
		
		// enumerate every node as starting node
		for (int i = 0; i < graph_size; ++i) {
			fill(pick.begin(), pick.end(), false);
			pick_node(i, findMicCostMIS);
		}
		

		return total_cost;
	}

// Assembly:
subq $0x1d8, %rsp            # imm = 0x1D8
movq %rdi, 0x1c8(%rsp)
movq %rsi, 0x1c0(%rsp)
movq 0x1c8(%rsp), %rdi
callq 0x4130
movq %rax, 0x1b0(%rsp)
movq 0x1c8(%rsp), %rdi
callq 0x4160
movq %rax, 0x1a8(%rsp)
movq 0x1b0(%rsp), %rdi
movq 0x1a8(%rsp), %rsi
callq 0x40f0
movl %eax, 0x1bc(%rsp)
movq 0x1c0(%rsp), %rdi
callq 0x4190
callq 0x41b0
movsd %xmm0, 0x1a0(%rsp)
movq $0x0, 0x198(%rsp)
leaq 0x160(%rsp), %rdi
callq 0x41c0
movslq 0x1bc(%rsp), %rax
movq %rax, 0x18(%rsp)
movb $0x0, 0x137(%rsp)
leaq 0x136(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x41d0
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rcx
leaq 0x138(%rsp), %rdi
leaq 0x137(%rsp), %rdx
callq 0x41e0
jmp 0x1889
leaq 0x136(%rsp), %rdi
callq 0x4260
leaq 0x1d7(%rsp), %rax
movq %rax, 0x108(%rsp)
movq 0x1c8(%rsp), %rax
movq %rax, 0x110(%rsp)
leaq 0x160(%rsp), %rcx
movq %rcx, 0x118(%rsp)
leaq 0x138(%rsp), %rdx
movq %rdx, 0xe0(%rsp)
movq %rcx, 0xe8(%rsp)
leaq 0x198(%rsp), %rax
movq %rax, 0xf0(%rsp)
leaq 0x1d6(%rsp), %rsi
movq %rsi, 0xf8(%rsp)
movq 0x1c8(%rsp), %rsi
movq %rsi, 0x100(%rsp)
leaq 0x1bc(%rsp), %rsi
movq %rsi, 0x78(%rsp)
movq %rdx, 0x80(%rsp)
leaq 0x108(%rsp), %rdx
movq %rdx, 0x88(%rsp)
leaq 0xe0(%rsp), %rdx
movq %rdx, 0x90(%rsp)
leaq 0xc0(%rsp), %rdi
movq %rdi, 0x98(%rsp)
movq %rcx, 0xa0(%rsp)
movq 0x1c0(%rsp), %rcx
movq %rcx, 0xa8(%rsp)
movq %rax, 0xb0(%rsp)
leaq 0x1a0(%rsp), %rax
movq %rax, 0xb8(%rsp)
leaq 0x78(%rsp), %rsi
callq 0x1cc0
jmp 0x198f
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
cmpl 0x1bc(%rsp), %eax
jge 0x1aa9
leaq 0x138(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x42e0
movq 0x10(%rsp), %rdi
movl %edx, 0x58(%rsp)
movq %rax, 0x50(%rsp)
movl 0x58(%rsp), %eax
movl %eax, 0x68(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x60(%rsp)
callq 0x4320
movl %edx, 0x38(%rsp)
movq %rax, 0x30(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0x48(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x40(%rsp)
movb $0x0, 0x2f(%rsp)
movq 0x60(%rsp), %rdi
movl 0x68(%rsp), %esi
movq 0x40(%rsp), %rdx
movl 0x48(%rsp), %ecx
leaq 0x2f(%rsp), %r8
callq 0x4270
jmp 0x1a1d
movl 0x74(%rsp), %esi
leaq 0xe0(%rsp), %rdi
leaq 0xc0(%rsp), %rdx
callq 0x1d70
jmp 0x1a38
jmp 0x1a3a
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x1997
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
leaq 0x136(%rsp), %rdi
callq 0x4260
jmp 0x1afa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
jmp 0x1aed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x4340
jmp 0x1aed
movsd 0x1a0(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x4340
leaq 0x138(%rsp), %rdi
callq 0x4350
leaq 0x160(%rsp), %rdi
callq 0x4360
movsd 0x8(%rsp), %xmm0
addq $0x1d8, %rsp            # imm = 0x1D8
retq
leaq 0x138(%rsp), %rdi
callq 0x4350
leaq 0x160(%rsp), %rdi
callq 0x4360
movq 0x128(%rsp), %rdi
callq 0x1180
nopw %cs:(%rax,%rax)