|
|
|
|
@ -133,3 +133,93 @@ solve(s1,s2,s3);
|
|
|
|
|
printf(“求解结果\n”):
|
|
|
|
|
print£(”s1:“);dispset(s1); print£(”s2:");dispset(s2): printf(”s3:“);dispset(s3);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
【问题描述】 求解自行车慢速比赛问题
|
|
|
|
|
一个美丽的小岛上有许多景点,景点之间有一条或者多条道路。现在进行自行车慢速比赛(最慢的选手获得冠军),工作人员在道路上标出自行车的单向行驶方向,所有比赛线路不会出现环,选手不能在中途的任何地方停下来,否则犯规,退出比赛。首先给定一行两个整数N和M,N为岛上的景点数(景点编号为0~N-1,N≤100),接下来的M行,每行为a、b、l,表示景点a和景点b之间的单向路径长度为L(L为整数)。最后一行为s和t,表示比赛的起点s和终点t。所有选手水平高超,都能够以自行车的最低速度行驶,并且所有自行车的最低速度相同。问冠军所走的路径长度是多少?假设只有一组测试数据。
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#define INF 0x3f3f3f3f //定义∞
|
|
|
|
|
#define MAXV 101
|
|
|
|
|
int A[MAXV][MAXV]; //邻接矩阵
|
|
|
|
|
int n,m;
|
|
|
|
|
int s,t;
|
|
|
|
|
int dist[MAXV];
|
|
|
|
|
void BellmanFord(int v) //贝尔曼-福特算法
|
|
|
|
|
{ int i,k,u;
|
|
|
|
|
for (i=0;i<n;i++)
|
|
|
|
|
dist[i]=A[v][i]; //对dist0[i]初始化
|
|
|
|
|
for (k=1;k<n;k++) //从dist0[u]递推出dist2[u], …,distn-1[u]循环n-2次
|
|
|
|
|
{ for (u=0;u<n; u++) //修改所有非顶点v的dist[]值
|
|
|
|
|
{ if (u!=v)
|
|
|
|
|
{ for (i=0;i<n;i++)
|
|
|
|
|
{ if (A[i][u]<INF && dist[u]>dist[i]+A[i][u])
|
|
|
|
|
dist[u]=dist[i]+A[i][u];
|
|
|
|
|
}
|
|
|
|
|
} } }
|
|
|
|
|
}
|
|
|
|
|
int main()
|
|
|
|
|
{ int i,j;
|
|
|
|
|
int a,b,l;
|
|
|
|
|
scanf("%d%d",&n,&m); //输入n、m
|
|
|
|
|
for (i=0;i<n;i++) //初始化邻接矩阵
|
|
|
|
|
for (j=0;j<n;j++)
|
|
|
|
|
if (i==j)
|
|
|
|
|
A[i][j]=0;
|
|
|
|
|
else
|
|
|
|
|
A[i][j]=INF;
|
|
|
|
|
for (i=0;i<m;i++) //输入边
|
|
|
|
|
{ scanf("%d%d%d",&a,&b,&l);
|
|
|
|
|
A[a][b]=-l;
|
|
|
|
|
}
|
|
|
|
|
scanf("%d%d",&s,&t); //输入s和t
|
|
|
|
|
BellmanFord(s); //采用BellmanFord算法求s出发的最短路径
|
|
|
|
|
printf("%d\n",-dist[t]); //输出结果
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
【问题描述】假设二叉树中所有结点值为int类型,采用二叉链存储。设计递归算法求二叉树bt中从根结点到叶子结点路径和最大的一条路径。编写完整的实验程序,并采用相应数据进行测试
|
|
|
|
|
1、引导学生回顾二叉树的基本运算算法:定义结点类型,选择存储结构,建立二叉链表,用括号表示法输出二叉树,释放二叉树等。
|
|
|
|
|
相应代码如下 :
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <string>
|
|
|
|
|
using namespace std;
|
|
|
|
|
typedef int ElemType;
|
|
|
|
|
typedef struct node
|
|
|
|
|
{ ElemType data; //数据元素
|
|
|
|
|
truct node *lchild; //指向左孩子结点
|
|
|
|
|
struct node *rchild; //指向右孩子结点
|
|
|
|
|
} BTNode; //二叉链结点类型
|
|
|
|
|
BTNode *CreateBTree(ElemType a[],ElemType b[],int n) //对应例2.8的算法由先序序列a[0..n-1]和中序序列b[0..n-1]建立二叉链
|
|
|
|
|
{
|
|
|
|
|
int k;
|
|
|
|
|
if (n<=0) return NULL;
|
|
|
|
|
ElemType root=a[0]; //根结点值
|
|
|
|
|
BTNode *bt=(BTNode *)malloc(sizeof(BTNode));
|
|
|
|
|
bt->data=root;
|
|
|
|
|
for (k=0;k<n;k++) //在b中查找b[k]=root的根结点
|
|
|
|
|
if (b[k]==root)
|
|
|
|
|
break;
|
|
|
|
|
bt->lchild=CreateBTree(a+1,b,k); //递归创建左子树
|
|
|
|
|
bt->rchild=CreateBTree(a+k+1,b+k+1,n-k-1); //递归创建右子树
|
|
|
|
|
return bt;
|
|
|
|
|
}
|
|
|
|
|
void DispBTree(BTNode *bt) //采用括号表示输出二叉链bt
|
|
|
|
|
{
|
|
|
|
|
if (bt!=NULL)
|
|
|
|
|
{ printf("%d",bt->data);
|
|
|
|
|
if (bt->lchild!=NULL || bt->rchild!=NULL)
|
|
|
|
|
{ printf("("); //有孩子结点时才输出(
|
|
|
|
|
DispBTree(bt->lchild); //递归处理左子树
|
|
|
|
|
if (bt->rchild!=NULL) printf(","); //有右孩子结点时才输出,
|
|
|
|
|
DispBTree(bt->rchild); //递归处理右子树
|
|
|
|
|
printf(")"); //有孩子结点时才输出)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void DestroyBTree(BTNode *&bt) //对应例2.9的算法
|
|
|
|
|
//释放以bt为根结点的二叉树
|
|
|
|
|
{ if (bt!=NULL)
|
|
|
|
|
{ DestroyBTree(bt->lchild);
|
|
|
|
|
DestroyBTree(bt->rchild);
|
|
|
|
|
free(bt);
|
|
|
|
|
}
|
|
|
|
|
}
|