赞
踩
已知一个加权有向图(为了计算方便,假设编号为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; }
- #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]){
- distance[j]=length+a[i][j];
- label[j]=i;
- e.length=distance[j];
- e.i=j;
- EnQueue(sq,e);
- }
- }
- }
- }
-
-
- 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;
- }
给定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; }
- #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.x[e.i] = 1; // 选择当前物品
- le.cw += w[e.i]; // 更新当前重量
- le.cv += v[e.i]; // 更新当前价值
- le.i++; // 准备好进入下一层
- if (le.cw <= c) { // 如果满足约束条件
- EnQueue(sq, le);
- }
- // 处理右孩子,不要该物品
- QNode re = e;
- // re.x[e.i] 已经是0,因为是从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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。