void complete2Tournament(IGraph &comp, IGraph &tour, bool unweighted = true){

	//if(comp.isComplete()){
	//	cout << "complete2Tournament" << endl;
		for (IGraph::vertex_iterator v = comp.begin(); v != comp.end(); v++){
			IGraph::vertex::iterator end = v->end();
			for (IGraph::vertex::iterator u = v->begin(); u != end; u++){
				if(!(tour.edgeExists(v->id,u->second->id) || tour.edgeExists(u->second->id, v->id))){
					double w1 = comp.getEdge(v->id, u->second->id);
					double w2 = comp.getEdge(u->second->id, v->id);
					
					double wVal = (unweighted)? 1 : abs(w1 - w2); 

					if(w1 > w2)
						tour.addEdge(v->id, u->second->id, (unweighted)? 1 : w1);
					else if(w1 < w2)
						tour.addEdge(u->second->id, v->id, (unweighted)? 1 : w2);
					else{
						tour.addEdge(u->second->id, v->id, (unweighted)? 1 : w2);
						tour.addEdge(v->id, u->second->id, (unweighted)? 1 : w1);
					}
				}
			}
		}
	//}
}
int tour_ham_merge_and_count(IGraph &tour, int *A, int *buffer, int ini, int fim, int meio){

	memset(buffer, 0, sizeof(int)*(fim-ini+1));

	int count = 0;

	int i = ini;
	int j = meio + 1;
	
	int k = 0;
	while(i < meio + 1 && j <= fim){
		if(tour.edgeExists(A[i], A[j])){
			buffer[k] = A[i];
			i++;
		}else{
			buffer[k] = A[j];
			count += meio - i + 1;
			j++;
		}
		k++;
	}

	if(i < meio + 1){
		memcpy(buffer + k, A + i, sizeof(int)*(meio-i+1));
	}else{
		memcpy(buffer + k, A + j, sizeof(int)*(fim-j+1));
	}
	
	memcpy(A + ini, buffer, sizeof(int)*(fim-ini+1));

	return count;
}
	void FAS_pivot(IGraph &graph, std::vector<int> &vertices){
		
		if(vertices.size() <= 1) return;
		// pick random pivot
		int i = vertices[rand()%(vertices.size())];
		
		std::vector<int> vL;
		std::vector<int> vR;
		
		for (int j = 0; j < vertices.size(); ++j)
		{
			if(i == vertices[j]) continue;

			if(graph.edgeExists(vertices[j], i)){
				vL.push_back(vertices[j]);
			}else if(graph.edgeExists(i, vertices[j])){
				vR.push_back(vertices[j]);
			}
		}
		
		FAS_pivot(graph, vL);
		FAS_pivot(graph, vR);
		
		vertices.clear();
		for (int k = 0; k < vL.size(); ++k)
		{
			vertices.push_back(vL[k]);
		}

		vertices.push_back(i);

		for (int k = 0; k < vR.size(); ++k)
		{
			vertices.push_back(vR[k]);
		}

	}