#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct Node {
int i, x[10];
bool worker[10];
int cost;
int lb;
bool operator<(const Node &obj) const {
return lb > obj.lb;
}
} ;
int n;
// 2 6 1 4 13
int *bestx;
int minCost = 9999;
void bound(Node &obj, int **c) {
int minSum = 0;
for ( int i1 = obj.i + 1; i1 < n; i1++) {
int minc = 9999;
for ( int j1 = 0; j1 < n; j1++)
if ( !obj.worker[j1] && c[i1][j1] < minc)
minc = c[i1][j1];
minSum += minc;
}
obj.lb = obj.cost + minSum;
}
void bfs(int **c) {
priority_queue<Node> q;
//初始化节点
Node e;
memset ( e.x, -1, sizeof ( e.x) ) ;
memset ( e.worker, false, sizeof ( e.worker) ) ;
e.i = -1, e.cost = 0;
bound ( e, c) ;
q.push ( e) ;
while (!q.empty()) {
Node e1 = q.top ( ) ;
q.pop ( ) ;
if (e1.i == n - 1) {
if (e1.cost < minCost) {
minCost = e.cost;
for ( int i = 0; i < n; i++)
bestx[i] = e1.x[i];
}
}
//遍历每个任务
for ( int j = 0; j < n; j++) {
Node e2 = e1;
//接e1节点后面没有分配任务的人开始
e2.i++;
if ( e2.worker[j])
continue;
//为第i个人分配j任务
e2.x[e2.i] = j;
//任务j分配完成
e2.worker[j] = true;
e2.cost += c[e2.i][j];
bound ( e2, c) ;
if ( e2.lb < minCost)
q.push ( e2) ;
}
}
}
int main() {
//录入问题规模,即二维数组的大小,行和列一样
//构造方阵
//可计算10以内,包括10的问题
scanf ( "%d" , &n) ;
bestx = new int[n];
//初始化矩阵
int **c = new int *[n];
for ( int i = 0; i < n; i++)
c[i] = new int[n];
//录入数据
for ( int i = 0; i < n; i++)
for ( int j = 0; j < n; j++)
scanf ( "%d" , &c[i][j]) ;
bfs ( c) ;
//打印数据
for ( int i = 0; i < n; i++)
printf ( "%d\t" , bestx[i] + 1) ;
printf ( "\n" ) ;
int sum = 0;
for ( int i = 0; i < n; i++)
sum += c[i][bestx[i]];
printf ( "%d\n" , sum) ;
delete[] bestx;
for ( int i = 0; i < n; i++)
delete[] c[i];
delete[] c;
return 0;
}
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct Node {
int i, x[4];
bool worker[4];
int cost;
int lb;
bool operator<(const Node &obj) const {
return lb > obj.lb;
}
} ;
int n = 4;
int c[4][4] = { { 9, 2, 7, 8} ,
{ 6, 4, 3, 7} ,
{ 5, 8, 1, 8} ,
{ 7, 6, 9, 4} } ;
// 2 6 1 4 13
int bestx[4];
int minCost = 9999;
void bound(Node &obj) {
int minSum = 0;
//int c[4][4] = { { 9, 2, 7, 8} ,
// { 6, 4, 3, 7} ,
// { 5, 8, 1, 8} ,
// { 7, 6, 9, 4} } ;
for ( int i1 = obj.i + 1; i1 < n; i1++) {
int minc = 9999;
for ( int j1 = 0; j1 < n; j1++)
if ( !obj.worker[j1] && c[i1][j1] < minc)
minc = c[i1][j1];
minSum += minc;
}
obj.lb = obj.cost + minSum;
}
void bfs() {
Node e, e1;
priority_queue<Node> q;
memset ( e.x, -1, sizeof ( e.x) ) ;
memset ( e.worker, false, sizeof ( e.worker) ) ;
e.i = -1, e.cost = 0;
bound ( e) ;
q.push ( e) ;
while (!q.empty()) {
e = q.top ( ) ;
q.pop ( ) ;
if (e.i == n - 1) {
if (e.cost < minCost) {
minCost = e.cost;
for ( int i = 0; i < n; i++)
bestx[i] = e.x[i];
}
}
//0
e1.i = e.i + 1;
//遍历每个任务
for ( int j = 0; j < n; j++) {
if ( e.worker[j])
continue;
for ( int i1 = 0; i1 < n; i1++) {
//将e节点中每个人选择的任务
//赋值给e1
e1.x[i1] = e.x[i1];
}
e1.x[e1.i] = j;
for ( int i2 = 0; i2 < n; i2++) {
e1.worker[i2] = e.worker[i2];
}
e1.worker[j] = true;
e1.cost = e.cost + c[e1.i][j];
bound ( e1) ;
if ( e1.lb < minCost)
q.push ( e1) ;
}
}
}
int main() {
bfs ( ) ;
int sum = 0;
for ( int i = 0; i < n; i++)
printf ( "%d\t" , bestx[i]) ;
printf ( "\n" ) ;
for ( int i = 0; i < n; i++)
sum += c[i][bestx[i]];
printf ( "%d\n" , sum) ;
return 0;
}