1.蛮力法
#include<stdio.h>
#include<vector>
#include<iostream>
using namespace std;
#define INF 99999
#define MAXN 21
int n=4;
int c[MAXN][MAXN]={
{9,2,7,8},{6,4,3,7},{5,8,1,8},{7,6,9,4}};
vector<vector<int> > ps;
void Insert(vector<int>s,int i,vector<vector<int> > &ps1){
vector<int>s1;
vector<int>::iterator it;
for(int j=0;j<i;j++){
s1=s;
it=s1.begin()+j;
s1.insert(it,i);
ps1.push_back(s1);
}
}
void Perm(int n){
vector<vector<int> > ps1;
vector<vector<int> >::iterator it;
vector<int>s,s1;
s.push_back(1);
ps.push_back(s);
for(int i=2;i<=n;i++){
ps1.clear();
for(it=ps.begin();it!=ps.end();it++) Insert(*it,i,ps1);
ps=ps1;
}
}
void Allocate(int n,int &mini,int &minc){
Perm(n);
for(int i=0;i<ps.size();i++){
int cost=0;
for(int j=0;j<ps[i].size();j++){
cost+=c[j][ps[i][j]-1];
}
if(cost<minc) {
minc=cost; mini=i;
}
}
}
int main(){
int mincost=INF,mini;
Allocate(n,mini,mincost);
for(int k=0;k<ps[mini].size();k++){
cout<<k+1<<" "<<ps[mini][k]<<endl;
}
cout<<mincost;
}
2.回溯法
#include<stdio.h>
#include<string.h>
#include<queue>
#include<vector>
#include<iostream>
using namespace std;
#define INF 99999
#define MAXN 21
int n=4;
int c[MAXN][MAXN]={
{0},{0,9,2,7,8},{0,6,4,3,7},{0,5,8,1,8},{0,7,6,9,4}};
int x[MAXN];
int cost=0;
int bestx[MAXN];
int mincost=INF;
bool worker[MAXN];
void dfs(int i){
if(i>n){
if(cost<mincost){
mincost=cost;
for(int j=1;j<=n;j++){
bestx[j]=x[j];
}
}
}
else {
for(int j=1;j<=n;j++){
if(!worker[j]){
worker[j]=true;
x[i]=j;
cost+=c[i][j];
dfs(i+1);
worker[j]=false;
x[i]=0;
cost-=c[i][j];
}
}
}
}
int main(){
memset(worker,0,sizeof(worker));
dfs(1);
for(int k=1;k<=n;k++){
cout<<k<<" "<<bestx[k]<<endl;
}
cout<<mincost;
}
3.优先队列式分支限界法
#include<stdio.h>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 21
int n=4;
int c[MAXN][MAXN]={
{0},{0,9,2,7,8},{0,6,4,3,7},{0,5,8,1,8},{0,7,6,9,4}};
int bestx[MAXN];
int minicost=INF;
int total=1;
struct NodeType{
int no,i;
int x[MAXN];
bool worker[MAXN];
int cost,lb;//lb下界
bool operator < (const NodeType & s) const {
return lb>s.lb;
}
};
void bound (NodeType &e){
int minsum=0;
for(int i1=e.i+1;i1<=n;i1++){
int minc=INF;
for(int j1=1;j1<=n;j1++) {
if(e.worker[j1]==false&&c[i1][j1]<minc)
minc=c[i1][j1];
}
minsum+=minc;
}
e.lb=e.cost+minsum;
}
void bfs(){
int j;
NodeType e,e1;
priority_queue<NodeType>qu;
memset(e.x,0,sizeof(e.x));
memset(e.worker,0,sizeof(e.worker));
e.i=0;
e.cost=0;
bound(e);
e.no=total++;
qu.push(e);
while(!qu.empty()){
e=qu.top();qu.pop();
if(e.i==n){
if(e.cost<minicost){
minicost=e.cost;
for(j=1;j<=n;j++){
bestx[j]=e.x[j];
}
}
}
e1.i=e.i+1;
for(int j=1;j<=n;j++){
if(e.worker[j]) continue;
for(int i1=1;i1<=n;i1++) e1.x[i1]=e.x[i1];
e1.x[e1.i]=j;
for(int i2=1;i2<=n;i2++) e1.worker[i2]=e.worker[i2];
e1.worker[j]=true;
e1.cost=e.cost+c[e1.i][j];
bound(e1);
e1.no=total++;
if(e.lb<minicost) qu.push(e1);
}
}
}
int main(){
bfs();
for(int k=1;k<=n;k++){
cout<<k<<" "<<bestx[k]<<endl;
}
cout<<minicost;
}