分支限界法是以广度优先遍历,可以用队列实现,附详细代码
#include <bits/stdc++.h>
using namespace std;
int Weight[100];//物品重量
int Value[100];//物品价值
int N;//总的物品数量
int n=-1;//创造树标记
int max_value=INT_MIN;//当前得出最大价值;
int max_weight;//背包限制的重量
struct A* max_pointer;//值最大时的节点
struct A* D[10000];//队列数组
struct A
{
struct A *lchild;//左节点
struct A *rchild;//右节点
struct A *parent;
int flag;//查询用到0表示没放入,1表示放入
int value;//节点价值
int weight;//节点重量
};
void createtree(struct A *B)//创造树,重点
{
n++;//代表相应的物品
if(n<N)
{
B->lchild=new(struct A)();//左节点表示不放入
B->lchild->value=B->value;//与父节点价值相等
B->lchild->weight=B->weight;//与父节点重量相等
B->lchild->flag=0;//表示没放入该物品
B->lchild->parent=B;//标记父母
createtree(B->lchild);//递归建树
n--;
B->rchild=(struct A*)malloc(sizeof(struct A));//右节点表示放入
B->rchild->value=B->value+Value[n];//价值为父节点价值+物品价值;
B->rchild->weight=B->weight+Weight[n];//重量为父节点重量+物品重量;
B->rchild->flag=1;//表示放入该物品
B->rchild->parent=B;//标记父母
createtree(B->rchild);//递归建树
n--;
}
else
{
B->lchild=NULL;
B->rchild=NULL;
}
}
void print(struct A*head)//可以用来查看树的结构
{ int a;
if(N>0)//刚好N可以表示层数,head->flag表示该节点有没有选中
{ a=N;
N--;
print(head->parent);
if(head->flag==1)//表示选中
cout<<a<<" ";
}
}
int main()
{
struct A* head;//根节点
head=(struct A*)malloc(sizeof(struct A));//分配空间
head->parent=NULL;
head->value=0;//价值初始化
head->weight=0;//重量初始化
cout<<"请输入背包容积:";
cin>>max_weight;//背包容积
cout<<"请输入物品数量:";
cin>>N;//物品数
cout<<"请输入各个物品的重量:";
for(int i=0; i<N; i++) //物品重量输入
{
cin>>Weight[i];
}
cout<<"请输入各个物品的价值:";
for(int i=0; i<N; i++) //物品价值输入
{
cin>>Value[i];
}
createtree(head);//创造树
int begin=0,end=0;//队列的头标记,尾标记
D[0]=head;
end++;//
while(begin!=end)//空队列
{
if(D[begin]->value>=max_value)//更新最大价值
{
max_value=D[begin]->value;//记录最大值
max_pointer=D[begin];//记录该节点
}
if(D[begin]->lchild&&D[begin]->lchild->weight<=max_weight)//入队列,可以放入剪枝条件
{
D[end]=D[begin]->lchild;
end++;
}
if(D[begin]->rchild&&D[begin]->rchild->weight<=max_weight)//入队列,可以放入剪枝条件
{
D[end]=D[begin]->rchild;
end++;
}
begin++;//头标记向后走
}
cout<<max_value<<endl;//输出结果
print(max_pointer);
}