当前位置:   article > 正文

算法设计与分析-分支限界_分支限界题目

分支限界题目

问题A: 分支限界法-单源最短路径问题

题目描述

 已知一个加权有向图(为了计算方便,假设编号为1的顶点是入度为0的源点,编号为n的顶点是出度为0的汇点,图中的顶点从1开始编号),要求计算图中从源点出发到汇点的最短距离及其对应的路径(逆向输出)。

输入

第1行输入两个整数,分别表示图G中顶点数n和边数m。
第2 - m+1行每行输入三个整数,分别表示顶点i和顶点j的编号以及由这两个顶点的有向边上的权。

输出

第1行输出源点到汇点的最短路径距离。
第2行输出汇点到源点的逆向最短路径。

样例输入

 复制

5 7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
样例输出

 复制

60
5 3 4 1
提示
#include <stdio.h>

#define INFINITY  65535
#define MaxSize 100 //顺序队列最大长度 

int n;  //图中的顶点个数 
int m; //图中的边的个数 
int a[20][20];//邻接矩阵 
int label[20]; // 存储源点到其余顶点最短路径上的最后一个顶点编号,0号单元不用
int distance[20]; // 存储从源点出发到其余各个顶点的最短距离,0号单元不用 

void CreateGraph() {
	int i,j,u,v,w;

	for(i=1; i<=n; i++){ // 初始化邻接矩阵
		for(j=1; j<=n; j++) a[i][j] = INFINITY;
	}
	for(i=1; i<=m; i++) { // 输入边信息填写有向图的邻接矩阵
		scanf("%d %d %d",&u,&v,&w);  // 边的信息包括顶点1和顶点2的编号以及它们之间的距离
		a[u][v]=w;
	}
}

typedef struct {
	int length; // 存储源点到此顶点的当前距离 
	int i; //存储顶点在图中的编号 
} QNode; //存放解空间树中的结点数据

typedef struct { //存放结点的顺序循环队列
	QNode Q[MaxSize];
	int front,rear;
} SqQueue;

void InitQueue(SqQueue &sq) { //队列初始化
	sq.front=0;
	sq.rear=0;
}

int QueueEmpty(SqQueue sq) {	//判断队列是否为空
	if(sq.front==sq.rear) {
		return 1;
	} else {
		return 0;
	}
}

int QueueFull(SqQueue sq) { //判断队列是否为满
	if(sq.front==(sq.rear+1)%MaxSize) {
		return 1;
	} else {
		return 0;
	}
}

void EnQueue(SqQueue &sq, QNode e) { //入队
	if(!QueueFull(sq)) {
		sq.Q[sq.rear]=e;
		sq.rear=(sq.rear+1)%MaxSize;
	} else {
		printf("Error:queue is full\n");
	}
}

void DeQueue(SqQueue &sq, QNode &e) { //出队
	if(!QueueEmpty(sq)) {
		e=sq.Q[sq.front];
		sq.front=(sq.front+1)%MaxSize;
	} else {
		printf("Error:queue is empty\n");
	}
}

void BB() {//从顶点1开始 

        SqQueue sq;
	InitQueue(sq);
	
	QNode e;
	e.length=0;
	e.i=1; // 构造根结点
	EnQueue(sq,e);

	while(!QueueEmpty(sq)) {
		DeQueue(sq,e);
		int i=e.i;
		int length=e.length;
		for(int j=1;j<=n;j++){
			if(a[i][j]<INFINITY && length+a[i][j]<distance[j]){
				________________________
			}
		} 	
	}
}


int main(void) {

	scanf("%d %d",&n,&m);

	CreateGraph();
	
	for(int i=1; i<=n; i++){ // 初始化源点到各个顶点的距离 
    	distance[i]=INFINITY;
	}
	distance[1]=0; // 源点编号为1 
    label[1]=0; // 表示1号顶点没有前驱结点 

	BB();

	printf("%d\n",distance[n]);
	
	for(int u=n; u!=0; u=label[u]) printf("%d ",u);

	return 0;
}
  1. #include <stdio.h>
  2. #define INFINITY 65535
  3. #define MaxSize 100 //顺序队列最大长度
  4. int n; //图中的顶点个数
  5. int m; //图中的边的个数
  6. int a[20][20];//邻接矩阵
  7. int label[20]; // 存储源点到其余顶点最短路径上的最后一个顶点编号,0号单元不用
  8. int distance[20]; // 存储从源点出发到其余各个顶点的最短距离,0号单元不用
  9. void CreateGraph() {
  10. int i,j,u,v,w;
  11. for(i=1; i<=n; i++){ // 初始化邻接矩阵
  12. for(j=1; j<=n; j++) a[i][j] = INFINITY;
  13. }
  14. for(i=1; i<=m; i++) { // 输入边信息填写有向图的邻接矩阵
  15. scanf("%d %d %d",&u,&v,&w); // 边的信息包括顶点1和顶点2的编号以及它们之间的距离
  16. a[u][v]=w;
  17. }
  18. }
  19. typedef struct {
  20. int length; // 存储源点到此顶点的当前距离
  21. int i; //存储顶点在图中的编号
  22. } QNode; //存放解空间树中的结点数据
  23. typedef struct { //存放结点的顺序循环队列
  24. QNode Q[MaxSize];
  25. int front,rear;
  26. } SqQueue;
  27. void InitQueue(SqQueue &sq) { //队列初始化
  28. sq.front=0;
  29. sq.rear=0;
  30. }
  31. int QueueEmpty(SqQueue sq) { //判断队列是否为空
  32. if(sq.front==sq.rear) {
  33. return 1;
  34. } else {
  35. return 0;
  36. }
  37. }
  38. int QueueFull(SqQueue sq) { //判断队列是否为满
  39. if(sq.front==(sq.rear+1)%MaxSize) {
  40. return 1;
  41. } else {
  42. return 0;
  43. }
  44. }
  45. void EnQueue(SqQueue &sq, QNode e) { //入队
  46. if(!QueueFull(sq)) {
  47. sq.Q[sq.rear]=e;
  48. sq.rear=(sq.rear+1)%MaxSize;
  49. } else {
  50. printf("Error:queue is full\n");
  51. }
  52. }
  53. void DeQueue(SqQueue &sq, QNode &e) { //出队
  54. if(!QueueEmpty(sq)) {
  55. e=sq.Q[sq.front];
  56. sq.front=(sq.front+1)%MaxSize;
  57. } else {
  58. printf("Error:queue is empty\n");
  59. }
  60. }
  61. void BB() {//从顶点1开始
  62. SqQueue sq;
  63. InitQueue(sq);
  64. QNode e;
  65. e.length=0;
  66. e.i=1; // 构造根结点
  67. EnQueue(sq,e);
  68. while(!QueueEmpty(sq)) {
  69. DeQueue(sq,e);
  70. int i=e.i;
  71. int length=e.length;
  72. for(int j=1;j<=n;j++){
  73. if(a[i][j]<INFINITY && length+a[i][j]<distance[j]){
  74. distance[j]=length+a[i][j];
  75. label[j]=i;
  76. e.length=distance[j];
  77. e.i=j;
  78. EnQueue(sq,e);
  79. }
  80. }
  81. }
  82. }
  83. int main(void) {
  84. scanf("%d %d",&n,&m);
  85. CreateGraph();
  86. for(int i=1; i<=n; i++){ // 初始化源点到各个顶点的距离
  87. distance[i]=INFINITY;
  88. }
  89. distance[1]=0; // 源点编号为1
  90. label[1]=0; // 表示1号顶点没有前驱结点
  91. BB();
  92. printf("%d\n",distance[n]);
  93. for(int u=n; u!=0; u=label[u]) printf("%d ",u);
  94. return 0;
  95. }

问题B: 分支限界法-0-1背包问题

题目描述

给定n种物品和一背包。物品i (1≤i≤n) 的重量是wi (wi > 0),其价值为vi (vi > 0),背包的容量为c (c > 0)。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 

输入

第1行输入两个整数分别表示物品的数量和背包容量。
第2行输入n个整数分别表示每个物品的重量。
第3行输入n个整数分别表示每个物品的获利。

输出

第1行输出整个背包的最大获利。

样例输入

 复制

3 50
45 25 25
28 15 15
样例输出

 复制

30
提示
 
 
#include <stdio.h> // 为了方便编写限界函数,假设按照单位重量获利递增的顺序输入每个物品的重量和获利。 #define MaxSize 100 //最多节点数 int n; //物品数量 int c; //背包容量 int w[MaxSize]; //依次存放各个物品的重量,0号单元不用 int v[MaxSize]; //依次存放各个物品的价值,0号单元不用 int bestx[MaxSize]; //存放程序执行过程中已经找到的当前最优解,0号单元不用 int bestv=0; //存放程序执行过程中已经找到的当前最优值 typedef struct { int cw; // 当前已放物品的重量 int cv; // 当前已放物品的获利 int i; //当前在解空间树中的层数,假设根结点是第1层 int x[MaxSize]; // 当前解向量 } QNode; //存放解空间树中的节点数据 typedef struct { //存放节点的顺序循环队列 QNode Q[MaxSize]; int front,rear; } SqQueue; void InitQueue(SqQueue &sq) { //队列初始化 sq.front=0; sq.rear=0; } int QueueEmpty(SqQueue sq) { //判断队列是否为空 if(sq.front==sq.rear) { return 1; } else { return 0; } } int QueueFull(SqQueue sq) { //判断队列是否为满 if(sq.front==(sq.rear+1)%MaxSize) { return 1; } else { return 0; } } void EnQueue(SqQueue &sq, QNode e) { //入队 if(!QueueFull(sq)) { sq.Q[sq.rear]=e; sq.rear=(sq.rear+1)%MaxSize; } else { printf("Error:queue is full\n"); } } void DeQueue(SqQueue &sq, QNode &e) { //出队 if(!QueueEmpty(sq)) { e=sq.Q[sq.front]; sq.front=(sq.front+1)%MaxSize; } else { printf("Error:queue is empty\n"); } } void BB() { SqQueue sq; InitQueue(sq); // 构造根结点 QNode e; e.cw=0; e.cv=0; e.i=1; EnQueue(sq,e); while(!QueueEmpty(sq)) { DeQueue(sq,e); if(e.i==n+1) {// 处理解空间树中的叶子结点 if(e.cv>=bestv){ bestv=e.cv; for(int j=1; j<=n; j++) { bestx[j]=e.x[j]; } } } else { // 处理解空间树中的非叶子结点 //处理左孩子,要该物品 QNode le=e; ___________ le.i++; // 准备好进入下一层 if(le.cw<=c) { // 如果满足约束条件 EnQueue(sq,le); } //处理右孩子,不要该物品 QNode re=e; _____________ re.i++; // 准备好进入下一层 EnQueue(sq,re); } } } int main(void) { scanf("%d %d",&n,&c); for(int i=1; i<=n; i++) { scanf("%d",&w[i]); } for(int i=1; i<=n; i++) { scanf("%d",&v[i]); } BB(); printf("%d\n",bestv); return 0; }
  1. #include <stdio.h>
  2. // 为了方便编写限界函数,假设按照单位重量获利递增的顺序输入每个物品的重量和获利。
  3. #define MaxSize 100 //最多节点数
  4. int n; //物品数量
  5. int c; //背包容量
  6. int w[MaxSize]; //依次存放各个物品的重量,0号单元不用
  7. int v[MaxSize]; //依次存放各个物品的价值,0号单元不用
  8. int bestx[MaxSize]; //存放程序执行过程中已经找到的当前最优解,0号单元不用
  9. int bestv=0; //存放程序执行过程中已经找到的当前最优值
  10. typedef struct {
  11. int cw; // 当前已放物品的重量
  12. int cv; // 当前已放物品的获利
  13. int i; //当前在解空间树中的层数,假设根结点是第1层
  14. int x[MaxSize]; // 当前解向量
  15. } QNode; //存放解空间树中的节点数据
  16. typedef struct { //存放节点的顺序循环队列
  17. QNode Q[MaxSize];
  18. int front,rear;
  19. } SqQueue;
  20. void InitQueue(SqQueue &sq) { //队列初始化
  21. sq.front=0;
  22. sq.rear=0;
  23. }
  24. int QueueEmpty(SqQueue sq) { //判断队列是否为空
  25. if(sq.front==sq.rear) {
  26. return 1;
  27. } else {
  28. return 0;
  29. }
  30. }
  31. int QueueFull(SqQueue sq) { //判断队列是否为满
  32. if(sq.front==(sq.rear+1)%MaxSize) {
  33. return 1;
  34. } else {
  35. return 0;
  36. }
  37. }
  38. void EnQueue(SqQueue &sq, QNode e) { //入队
  39. if(!QueueFull(sq)) {
  40. sq.Q[sq.rear]=e;
  41. sq.rear=(sq.rear+1)%MaxSize;
  42. } else {
  43. printf("Error:queue is full\n");
  44. }
  45. }
  46. void DeQueue(SqQueue &sq, QNode &e) { //出队
  47. if(!QueueEmpty(sq)) {
  48. e=sq.Q[sq.front];
  49. sq.front=(sq.front+1)%MaxSize;
  50. } else {
  51. printf("Error:queue is empty\n");
  52. }
  53. }
  54. void BB() {
  55. SqQueue sq;
  56. InitQueue(sq);
  57. // 构造根结点
  58. QNode e;
  59. e.cw=0;
  60. e.cv=0;
  61. e.i=1;
  62. EnQueue(sq,e);
  63. while(!QueueEmpty(sq)) {
  64. DeQueue(sq,e);
  65. if(e.i==n+1) {// 处理解空间树中的叶子结点
  66. if(e.cv>=bestv){
  67. bestv=e.cv;
  68. for(int j=1; j<=n; j++) {
  69. bestx[j]=e.x[j];
  70. }
  71. }
  72. } else { // 处理解空间树中的非叶子结点
  73. //处理左孩子,要该物品
  74. QNode le = e;
  75. le.x[e.i] = 1; // 选择当前物品
  76. le.cw += w[e.i]; // 更新当前重量
  77. le.cv += v[e.i]; // 更新当前价值
  78. le.i++; // 准备好进入下一层
  79. if (le.cw <= c) { // 如果满足约束条件
  80. EnQueue(sq, le);
  81. }
  82. // 处理右孩子,不要该物品
  83. QNode re = e;
  84. // re.x[e.i] 已经是0,因为是从e复制过来的
  85. re.i++; // 准备好进入下一层
  86. EnQueue(sq, re);
  87. }
  88. }
  89. }
  90. int main(void) {
  91. scanf("%d %d",&n,&c);
  92. for(int i=1; i<=n; i++) {
  93. scanf("%d",&w[i]);
  94. }
  95. for(int i=1; i<=n; i++) {
  96. scanf("%d",&v[i]);
  97. }
  98. BB();
  99. printf("%d\n",bestv);
  100. return 0;
  101. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号