func calculate_plus_cost(matrix tsp_types.MatrixType, n int) (bool, tsp_types.DataType) {
	cost := tsp_types.DataType(0)
	// every row
	for i := 0; i < n; i++ {
		min_value := tsp_types.POSITIVE_INF
		// looking min value in row
		infinity_count := 0
		for j := 0; j < n; j++ {
			if matrix[i*n+j] == tsp_types.POSITIVE_INF {
				infinity_count++
			} else if matrix[i*n+j] < min_value {
				min_value = matrix[i*n+j]
			}
		}
		// if all elements in row are infinite then return
		if infinity_count == n {
			return false, tsp_types.DataType(0)
		}
		if min_value != 0 {
			// subtract min value from entire row
			for j := 0; j < n; j++ {
				if matrix[i*n+j] != tsp_types.POSITIVE_INF {
					matrix[i*n+j] -= min_value
				}
			}
			// add min value to cost
			cost += min_value
		}
	}
	// every collum
	for i := 0; i < n; i++ {
		min_value := tsp_types.POSITIVE_INF
		// looking min value in collum
		infinity_count := 0
		for j := 0; j < n; j++ {
			if matrix[j*n+i] == tsp_types.POSITIVE_INF {
				infinity_count++
			} else if matrix[j*n+i] < min_value {
				min_value = matrix[j*n+i]
			}
		}
		// if all elements in collum are infinite then return
		if infinity_count == n {
			return false, tsp_types.DataType(0)
		}
		if min_value != 0 {
			// subtract min value from entire column
			for j := 0; j < n; j++ {
				if matrix[j*n+i] != tsp_types.POSITIVE_INF {
					matrix[j*n+i] -= min_value
				}
			}
			// add min value to cost
			cost += min_value
		}
	}
	return true, cost
}
func listen_server(conn *net.Conn, logger *log.Logger, curr_task_info *CurrTaskInfo) {
	for {
		var data_size int64
		err := binary.Read(*conn, binary.LittleEndian, &data_size)
		if err != nil {
			logger.Printf("Reading data size (client) error: %v\n", err)
			return
		}
		if log_enable {
			logger.Printf("Read new data\n")
		} else {
			fmt.Printf("\n")
		}
		data := make([]byte, data_size)
		_, err = (*conn).Read(data)
		switch string(data[0]) {
		case "q":
			return
		case "m":
			param_vec := strings.Split(string(data[1:]), " ")
			if len(param_vec) != 2 {
				logger.Println("min cost error: param count != 2")
				return
			}
			task_id, err := strconv.Atoi(param_vec[0])
			if err != nil {
				logger.Printf("task id convert error: %v\n", err)
				return
			}
			min_cost, err := strconv.Atoi(param_vec[1])
			if err != nil {
				logger.Printf("min cost convert error: %v\n", err)
				return
			}
			if curr_task_info.TaskID < 0 {
				curr_task_info.TaskID = task_id
				curr_task_info.MinCost.Set(tsp_types.DataType(min_cost))
			} else if task_id == curr_task_info.TaskID {
				curr_task_info.MinCost.Set(tsp_types.DataType(min_cost))
			}
		default:
			task_str := string(data[1:])
			sep_index := strings.Index(task_str, " ")
			new_task_id, err := strconv.Atoi(task_str[:sep_index])
			if err != nil {
				logger.Printf("curr task id convert error: %v\n", err)
				return
			}
			curr_task_info.TaskID = new_task_id
			go solve_task(task_str[sep_index+1:], conn, logger, curr_task_info)
		}
	}
	defer (*conn).Close()
}
func find_heavier_zero(matrix tsp_types.MatrixType, n int) tsp_types.ZeroInfoType {
	heavier_zero := tsp_types.ZeroInfoType{0, 0, tsp_types.NEGATIVE_INF}
	for i := 0; i < n; i++ {
		// for every zero in row
		for j := 0; j < n; j++ {
			if matrix[i*n+j] == 0 {
				// find min element in row
				weight := tsp_types.DataType(0)
				min_value := tsp_types.POSITIVE_INF
				for z := 0; z < n; z++ {
					if (z != j) && (matrix[i*n+z] < min_value) && (matrix[i*n+z] != tsp_types.POSITIVE_INF) {
						min_value = matrix[i*n+z]
					}
				}
				if min_value != tsp_types.POSITIVE_INF {
					weight += min_value
				}
				// find min element in collum
				min_value = tsp_types.POSITIVE_INF
				for z := 0; z < n; z++ {
					if (z != i) && (matrix[z*n+j] < min_value) && (matrix[z*n+j] != tsp_types.POSITIVE_INF) {
						min_value = matrix[z*n+j]
					}
				}
				if min_value != tsp_types.POSITIVE_INF {
					weight += min_value
				}
				// remember new zero
				if heavier_zero.Weight < weight {
					heavier_zero = tsp_types.ZeroInfoType{i, j, weight}
				}
			}
		}
	}
	return heavier_zero
}