工作分配问题
问题描述:设有n件工作分配给n个人。将工作i分配给第j个人的费用为cij,请设计算法,为每个人都分配1件不同的工作,并使得总费用达到最小。
实现提示:该问题的解空间是一棵排列树,可用搜索排列树的回溯框架实现。
代码如下:
#include<iostream>
#include<climits>
using namespace std;
int work[100];// 工作数组,用于存储工作编号
int work_fee[100][100];// 每个工人对应的每个工作的费用
int n, minsum= INT_MAX, newsum=0;// n表示工人个数,minsum表示最小费用和,newsum表示最新费用和
void backTrack(int k) {
int number; // 工作编号
if (k > n) {// 到达叶子节点
if (newsum < minsum) { // 当最新费用小于当前最小费用时,更新最小费用
minsum = newsum;
}
return;
}
else {// 未到达叶子节点,继续
for (int i = k; i <= n; i++) {
number = work[i]; // 工作编号
newsum = newsum + work_fee[k][number];// 将当前工人k的number号工作加入最新工作费用
swap(work[k], work[i]);// 交换两个位置上的工作编号
if (newsum < minsum) { //当最新费用小于当前最小费用,继续下一个数
backTrack(k + 1);
}
swap(work[k], work[i]);// 还原之前交换的工作编号
newsum = newsum - work_fee[k][number];// 减去之前加入的数
}
}
}
int main() {
cin >> n; // 输入工人数
for (int i = 1; i <=n; i++) { // 初始化工作费用
for (int j = 1; j <= n; j++) {
cin >> work_fee[i][j];
}
}
for (int i = 1; i <= n; i++) {// 初始化工作编号
work[i] = i;
}
backTrack(1);// 回溯查找
cout << minsum << endl; // 输出最小费用
return 0;
}