实验六 分支界限法
第1关:0-1背包
题目描述:
任务要求
输出一个数,代表能装入的最大价值
测试输入:
4 7
3 5 2 1
9 10 7 4
预期输出:
20
分析:
无
代码实现:
#include <iostream>
#include <algorithm> //sort函数包含的头文件
using namespace std;
typedef struct p
{
struct p *pr;
int wt;
int vt;
int ch; //标志
int lev;
} EM;
typedef struct
{
EM *em[1000];
int start;
int tail;
} queue;
bool cmp(EM *a, EM *b)
{
return a->vt > b->vt;
}
void add(queue *q, EM *em)
{
q->em[q->tail] = em;
q->tail++;
if (q->tail - q->start > 1)
{
sort(q->em + (q->start), (q->em) + (q->tail), cmp);
}
return;
}
EM *del(queue *q)
{
q->start++;
return q->em[q->start - 1];
}
void Add_Q(queue *Q, EM *em, int wt, int vt, int i, int n, int ch)
{
EM *newE = (EM *)malloc(sizeof(EM));
newE->pr = em;
newE->vt = vt;
newE->wt = wt;
newE->ch = ch;
newE->lev = i;
add(Q, newE);
}
int BestValue(int c, int n, int w[], int v[])
{
queue *Q = (queue *)malloc(sizeof(queue));
Q->start = Q->tail = 0;
EM *Em = (EM *)malloc(sizeof(EM));
Em->pr = NULL;
Em->lev = 0;
Em->vt = 0;
Em->wt = 0;
while (Em->lev <= n)
{
if (Em->wt + w[Em->lev + 1] <= c)
{
Add_Q(Q, Em, Em->wt + w[Em->lev + 1], Em->vt + v[Em->lev + 1], Em->lev + 1, n, 1);
}
Add_Q(Q, Em, Em->wt, Em->vt, Em->lev + 1, n, 1);
Em = del(Q);
}
return Em->vt;
}
int main()
{
int n, c;
cin>>n>>c;
int w[n + 1], v[n + 1];
for (int i = 1; i <= n; i++)
{
cin >> w[i];
}
for (int i = 1; i <= n; i++)
{
cin >> v[i];
}
cout << BestValue(c, n, w, v) << endl;
return 0;
}
第2关:装载问题 (最优队列法)
题目描述:
输入格式
第一行输入n,代表有n个城市。
接下来n行每行输入n个数,第i行j列的值代表i市到j市的距离,0代表城市之间不通
注意:起点和终点都为1
n<7,城市之间的距离都不超过100
输出格式
第一行输出最少的旅行费用
Sample Input
4
0 30 6 4
30 0 5 10
6 5 0 20
4 10 20 0
Sample Output
25
分析:
无
代码实现:
#include <iostream>
#include <algorithm> //sort函数包含的头文件
using namespace std;
typedef struct data_EM
{
struct data_EM *pr;
int vt;
int lev;
int *city; //记录当前已经去过的城市
} EM;
typedef struct data_Q
{
EM *em[100];
int start;
int tail;
} Q;
bool cmp(EM *a, EM *b)
{
return a->vt < b->vt;
}
void add_e(Q *q, EM *em)
{
q->em[q->tail] = em;
q->tail++;
if (q->tail - q->start > 1)
{
sort(q->em + (q->start), (q->em) + (q->tail), cmp);
}
return;
}
EM *del_e(Q *q)
{
q->start++;
return q->em[q->start - 1];
}
void add_Q(Q *q, EM *em, int vt, int i, int city)
{
EM *newEm = (EM *)malloc(sizeof(EM));
newEm->pr = em;
newEm->lev = i;
newEm->vt = vt;
newEm->city = (int *)malloc(sizeof(int) * i);
newEm->city[i - 1] = city;
for (int j = 0; j < i - 1; j++)
{
newEm->city[j] = em->city[j];
}
add_e(q, newEm);
return;
}
int BestTsp(int **T, int n)
{
Q *q = (Q *)malloc(sizeof(Q));
EM *Em = (EM *)malloc(sizeof(EM));
q->start=q->tail=0;
Em->pr = NULL;
Em->vt = 0;
Em->city = (int *)malloc(sizeof(int));
Em->city[0] = 1;
Em->lev = 1;
while (Em->lev <= n)
{
for (int j = 2; j <= n; j++)
{
bool ctiy_k = true;
for (int k = 0; k < Em->lev; k++)
{
if (j == Em->city[k])
{
ctiy_k = false;
}
}
if (ctiy_k)
{
add_Q(q, Em, T[Em->city[Em->lev - 1]][j] + Em->vt + (Em->lev + 1 == n ? T[j][1] : 0), Em->lev + 1, j);
}
}
Em = del_e(q);
if (Em->lev == n || q->start == q->tail)
{
break;
}
}
return Em->vt;
}
int main()
{
int n;
cin >> n;
int **T = (int **)malloc(sizeof(int *) * (n + 1));
for (int i = 1; i <= n; i++)
{
T[i] = (int *)malloc(sizeof(int));
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> T[i][j];
}
}
cout << BestTsp(T, n) << endl;
return 0;
}
注:答案不唯一,仅供参考。