100 | 25 | 41 | 32 | 28 |
5 | 100 | 18 | 31 | 26 |
20 | 16 | 100 | 7 | 1 |
10 | 51 | 25 | 100 | 6 |
23 | 9 | 7 | 11 | 100 |
#include<iostream>
#include<fstream>
using namespace std;
typedef int Type;
#define N 5
#define ZERO 0
#define MAX 1000
typedef struct node_data {
Type c[N][N];
int row_init[N];
int col_init[N];
int row_cur[N];
int col_cur[N];
int ad[N];
int k;
Type w;
struct node_data* next;
}NODE;
Type c[N][N];
Type ad[N];
Type row_min(NODE* node, int row, Type& second)
{
Type temp;
int i;
int flag = 0;
if (node->c[row][0] < node->c[row][1]) {
temp = node->c[row][0];
second = node->c[row][1];
}
else {
temp = node->c[row][1];
second = node->c[row][0];
}
for (i = 2; i < node->k; i++) {
if (node->c[row][i] < temp) {
second = temp;
temp = node->c[row][i];
}
else if (node->c[row][i] < second)
second = node->c[row][i];
}
for (i = 0; i < node->k; i++)
if (node->c[row][i] == MAX)
flag++;
if (node->k == flag)
return 0;
return temp;
}
Type col_min(NODE* node, int col, Type& second)
{
Type temp;
int i;
int flag = 0;
if (node->c[0][col] < node->c[1][col]) {
temp = node->c[0][col];
second = node->c[1][col];
}
else {
temp = node->c[1][col];
second = node->c[0][col];
}
for (i = 2; i < node->k; i++) {
if (node->c[i][col] < temp) {
second = temp;
temp = node->c[i][col];;
}
else if (node->c[i][col] < second)
second = node->c[i][col];
}
for (i = 0; i < node->k; i++)
if (node->c[i][col] == MAX)
flag++;
if (node->k == flag)
return 0;
return temp;
}
Type array_red(NODE* node)
{
int i, j;
Type temp, temp1, sum = ZERO;
for (i = 0; i < node->k; i++) {
temp = row_min(node, i, temp1);
for (j = 0; j < node->k; j++) {
if (node->c[i][j] == MAX)
continue;
node->c[i][j] -= temp;
}
sum += temp;
}
for (j = 0; j < node->k; j++) {
temp = col_min(node, j, temp1);
for (i = 0; i < node->k; i++) {
if (node->c[i][j] == MAX)
continue;
node->c[i][j] -= temp;
}
sum += temp;
}
return sum;
}
Type edge_sel(NODE* node, int& vk, int& vl)
{
int i, j;
Type temp, d = ZERO;
Type* row_value = new Type[node->k];
Type* col_value = new Type[node->k];
for (i = 0; i < node->k; i++)
row_min(node, i, row_value[i]);
for (i = 0; i < node->k; i++)
col_min(node, i, col_value[i]);
for (i = 0; i < node->k; i++) {
for (j = 0; j < node->k; j++) {
if (node->c[i][j] == ZERO) {
temp = row_value[i] + col_value[j];
if (temp > d) {
d = temp;
vk = i;
vl = j;
}
}
}
}
delete row_value;
delete col_value;
return d;
}
void del_rowcol(NODE* node, int vk, int vl)
{
int i, j, vk1, vl1;
for (i = vk; i < node->k - 1; i++)
for (j = 0; j < vl; j++)
node->c[i][j] = node->c[i + 1][j];
for (j = vl; j < node->k - 1; j++)
for (i = 0; i < vk; i++)
node->c[i][j] = node->c[i][j + 1];
for (i = vk; i < node->k - 1; i++)
for (j = vl; j < node->k - 1; j++)
node->c[i][j] = node->c[i + 1][j + 1];
vk1 = node->row_init[vk];
node->row_cur[vk1] = -1;
for (i = vk1 + 1; i < N; i++)
node->row_cur[i]--;
vl1 = node->col_init[vl];
node->col_cur[vl1] = -1;
for (i = vl1 + 1; i < N; i++)
node->col_cur[i]--;
for (i = vk; i < node->k - 1; i++) {
node->row_init[i] = node->row_init[i + 1];
}
for (i = vl; i < node->k - 1; i++)
node->col_init[i] = node->col_init[i + 1];
node->k--;
}
void edg_byp(NODE* node, int vk, int vl)
{
int k, l;
vk = node->row_init[vk];
vl = node->col_init[vl];
node->ad[vk] = vl;
k = node->row_cur[vl];
l = node->col_cur[vk];
if ((k > 0) && (l >= 0)) {
node->c[k][l] = MAX;
}
}
NODE* initial(Type c[][N], int n)
{
int i, j;
NODE* node = new NODE;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) {
node->c[i][j] = c[i][j];
}
for (i = 0; i < n; i++) {
node->row_init[i] = i;
node->col_init[i] = i;
node->row_cur[i] = i;
node->col_cur[i] = i;
}
for (i = 0; i < n; i++) {
node->ad[i] = -1;
}
node->k = n;
return node;
}
void Q_insert(NODE* qbase, NODE* xnode) {
NODE* p;
if (qbase->next == NULL) {
qbase->next = xnode;
xnode->next = NULL;
}
else if (xnode->w < qbase->next->w) {
xnode->next = qbase->next;
qbase->next = xnode;
}
else {
p = qbase->next;
while (p->next) {
if ((xnode->w > p->w) && (xnode->w < p->next->w)) {
xnode->next = p->next;
p->next = xnode;
break;
}
p = p->next;
}
if (p->next == NULL) {
p->next = xnode;
xnode->next = NULL;
}
}
p = qbase->next;
}
NODE* Q_delete(NODE* qbase) {
NODE* p;
p = qbase->next;
qbase->next = p->next;
return p;
}
template <class Type>
Type traveling_salesman(Type c[][N], int n, int ad[])
{
int i, j, vk, vl;
Type d, w, bound = MAX;
NODE* xnode, * ynode, * znode, * qbase;
qbase = new NODE;
qbase->next = NULL;
xnode = initial(c, n);
xnode->w = array_red(xnode);
while (xnode->k != 0) {
d = edge_sel(xnode, vk, vl);
znode = new NODE;
*znode = *xnode;
znode->c[vk][vl] = MAX;
array_red(znode);
znode->w = xnode->w + d;
if (znode->w < bound)
Q_insert(qbase, znode);
else delete znode;
ynode = new NODE;
*ynode = *xnode;
edg_byp(ynode, vk, vl);
ynode->c[vl][vk] = MAX;
del_rowcol(ynode, vk, vl);
ynode->w = array_red(ynode);
ynode->w += xnode->w;
if (ynode->k == 2) {
if ((ynode->c[0][0] == ZERO) &&
(ynode->c[1][1] == ZERO)) {
ynode->ad[ynode->row_init[0]] = ynode->col_init[0];
ynode->ad[ynode->row_init[1]] = ynode->col_init[1];
}
else {
ynode->ad[ynode->row_init[0]] = ynode->col_init[1];
ynode->ad[ynode->row_init[1]] = ynode->col_init[0];
}
ynode->k = 0;
}
if (ynode->w < bound) {
Q_insert(qbase, ynode);
if (ynode->k == 0)
bound = ynode->w;
}
else delete ynode;
xnode = Q_delete(qbase);
}
w = xnode->w;
for (i = 0; i < n; i++) {
ad[i] = xnode->ad[i];
}
delete xnode;
while (qbase->next) {
xnode = Q_delete(qbase);
delete xnode;
}
return w;
}
void main() {
int i, j;
ifstream fin("1.txt");
if (!fin) {
cout << "cannpt open file!" << endl;
exit(0);
}
for (i = 0; i < N; i++)
for (j = 0; j < N; j++) {
fin >> c[i][j];
}
fin.close();
cout << traveling_salesman(c, N, ad) << endl;
cout << "\t";
for (i = 0; i < N; i++)
cout << i << "\t";
cout << endl;
cout << "ad:\t";
for (i = 0; i < N; i++)
cout << ad[i] << "\t";
cout << endl;
}