5-1最小生成树(普里姆算法)
#include
#define MVNum 100 #define MaxInt 32767 using namespace std; struct edge{ char adjvex; int lowcost; }closedge[MVNum]; typedef struct{ char vexs[MVNum]; int arcs[MVNum][MVNum]; int vexnum,arcnum; }AMGraph; int LocateVex(AMGraph G , char v);//实现细节隐藏 int CreateUDN(AMGraph &G);//实现细节隐藏 int Min(AMGraph G){ int i; int index = -1; int min = MaxInt; for(i = 0 ; i < G.vexnum ; ++i){ if(_____________){ min = closedge[i].lowcost; index = i; } } return index; } void MiniSpanTree_Prim(AMGraph G, char u){ int k , j , i; char u0 , v0; k =LocateVex(G, u); for(j = 0; j < G.vexnum; ++j){ if(j != k){ closedge[j].adjvex = _____________3分; closedge[j].lowcost = _____________3分; } } closedge[k].lowcost = _____________3分; for(i = 1; i < G.vexnum; ++i){ k = _____________3分; u0 = closedge[k].adjvex; v0 = G.vexs[k]; cout << u0 << "->" << v0 << endl; closedge[k].lowcost = _____________3分; for(j = 0; j < G.vexnum; ++j) if(G.arcs[k][j] < closedge[j].lowcost){ closedge[j].adjvex = _____________3分; closedge[j].lowcost = _____________3分; } } } int main(){ AMGraph G; CreateUDN(G); char u; cin >> u; MiniSpanTree_Prim(G , u); return 0; } 参考答案:
(1)closedge[i].lowcost!=0 && closedge[i].lowcost
5-2最短路径(迪杰斯特拉算法)
#include
using namespace std; #define MaxInt 32767 #define MVNum 100 typedef char VerTexType; typedef int ArcType; int *D=new int[MVNum]; bool *S=new bool[MVNum]; int *Path=new int[MVNum]; typedef struct{ VerTexType vexs[MVNum]; ArcType arcs[MVNum][MVNum]; int vexnum,arcnum; }AMGraph; int LocateVex(AMGraph G , VerTexType v)//该实现细节隐藏 void CreateUDN(AMGraph &G);//该实现细节隐藏 void ShortestPath_DIJ(AMGraph G, int v0){ int v , i , w , min; int n = G.vexnum; for(v = 0; v < n; ++v){ S[v] = false; D[v] = G.arcs[v0][v]; if(D[v] < MaxInt) Path [v] = v0; else Path [v] = -1; } S[v0]=true; D[v0]=0; for(i = 1;i < n; ++i){ min= MaxInt; for(w = 0; w < n; ++w) if(_____________3分){ v = w; min = D[w]; } S[v]=true; for(w = 0;w < n; ++w) if(_____________3分){ D[w] = _____________3分; Path [w] = _____________3分; } } } void DisplayPath(AMGraph G , int begin ,int temp ){ if(Path[temp] != -1){ DisplayPath(G , begin ,Path[temp]); cout << G.vexs[Path[temp]] << "->"; } } int main() { AMGraph G; int i , j ,num_start , num_destination; VerTexType start , destination; CreateUDN(G); cin >> start >> destination; num_start = LocateVex(G , start); num_destination = LocateVex(G , destination); ShortestPath_DIJ(G , num_start); DisplayPath(G , num_start , num_destination); cout << G.vexs[num_destination]< 参考答案:
(1)!S[w]&&D[w]
6-1 孤勇者探险(图的深度优先遍历)
一款名为“孤勇者探险”的游戏,游戏中共有若干个小岛,每个岛上均有怪兽,闯关者打倒岛上的怪兽则可获得该岛对应的游戏积分(每个岛的积分根据难度可能不相同),编写程序求出最终闯关成功者(闯过所有小岛)共获得多少积分,并给出对应的闯关行进路线。
思路提示:
游戏地图可抽象为图结构,且一定为连通图,例如:图中顶点的值则为每个小岛对应的积分,‘0’小岛为起点,从0号开始按深度优先遍历顺序闯关,将各个顶点的值累加则为最终获得得分,同时输出对应的闯关行进路线。
函数接口定义:
在这里描述函数接口。例如: void CreateUDG(AMGraph &G); //创建图,采用邻接矩阵存储 int DFS(AMGraph G, int v);//以v为起点深度优先遍历,求出各顶点值的和作为函数返回值
在这里解释接口参数。例如:其中
N
和D
都是用户传入的参数。N
的值不超过int
的范围;D
是[0, 9]区间内的个位数。函数须返回N
中D
出现的次数。裁判测试程序样例:
#include
#include #define MVNum 100 int visited[MVNum]; typedef struct{ int vexs[MVNum]; //顶点向量,各小岛对应积分 int arcs[MVNum][MVNum]; //邻接矩阵 int vexnum,arcnum; //顶点数,边数 }AMGraph; void CreateUDG(AMGraph &G); //创建图,采用邻接矩阵存储 int DFS(AMGraph G, int v);//以v为起点深度优先遍历,求出各顶点值的和作为返回值 int LocateVex(AMGraph G,int u) //查询顶点u的下标 { int i; for(i=0;i =0) printf("\n%d",DFS(G,i)); return 0; } /* 请在这里填写答案 */ 输入样例:
第1行依次输入各个小岛对应得分(整数),即顶点的值,以-1结束(顶点不包含-1)
接下来若干行输入每条边的信息,格式为:v1空格v2(v1、v2为小岛对应的下标),直到输入‘-1 -1’结束。0 1 2 3 4 5 6 -1 0 3 0 4 3 2 3 1 2 5 1 5 4 5 5 6 -1 -1
输出样例:
输出两行数据,第一行为行进路线,以小岛的积分(即顶点的值)作为小岛标识,每个标识之间间隔一个空格,第二行为一个整数,为最终获得积分。
0 3 1 5 2 4 6 21
参考答案:
void CreateUDG(AMGraph &G) { int i=0,j=0,k=0; scanf("%d",&G.vexs[i]); while(G.vexs[i]!=-1) { i++; scanf("%d",&G.vexs[i]); } G.vexnum=i; for(i=0;i
6-2 图的广度遍历-邻接表实现
本题要求实现邻接表存储图的广度优先遍历。
函数接口定义:
void BFS(ALGraph *G,int i);
其中ALGraph是邻接表存储的图,定义如下:
#define MAX_VERTEX_NUM 10 /*定义最大顶点数*/ typedef int Vertex; typedef struct ArcNode{ /*表结点*/ int adjvex; /*邻接点域*/ struct ArcNode *nextarc; /*指向下一个表结点*/ }ArcNode; typedef struct VNode{ /*头结点*/ Vertex data; /*顶点域*/ ArcNode *firstarc; /*指向第一个表结点*/ }VNode,AdjList[MAX_VERTEX_NUM]; /*AdjList是数组类型*/ typedef struct { AdjList vertices; /*邻接表中数组定义*/ int vexnum,arcnum; /*图中当前顶点数和边数*/ } ALGraph; /*图类型*/
裁判测试程序样例:
#include"stdio.h" #include"stdlib.h" #define MAX_VERTEX_NUM 10 /*定义最大顶点数*/ typedef int Vertex; typedef struct ArcNode{ /*表结点*/ int adjvex; /*邻接点域*/ struct ArcNode *nextarc; /*指向下一个表结点*/ }ArcNode; typedef struct VNode{ /*头结点*/ Vertex data; /*顶点域*/ ArcNode *firstarc; /*指向第一个表结点*/ }VNode,AdjList[MAX_VERTEX_NUM]; /*AdjList是数组类型*/ typedef struct { AdjList vertices; /*邻接表中数组定义*/ int vexnum,arcnum; /*图中当前顶点数和边数*/ } ALGraph; /*图类型*/ typedef enum{FALSE,TRUE} Boolean; Boolean visited[MAX_VERTEX_NUM];/*定义标志向量,为全局变量*/ void CreatALGraph(ALGraph *G);/* 创建图并且将Visited初始化为false;裁判实现,细节不表 */ void BFS(ALGraph *G,int v); int main() { Vertex v; ALGraph G; CreatALGraph(&G); scanf("%d", &v); printf("BFS from %d:",v); BFS(&G,v); return 0; } /* 你的代码将被嵌在这里 */
对于给定图:
输入样例:
7 9 0 2 0 3 0 4 1 3 1 5 2 3 2 5 4 5 5 6 5
输出样例:
BFS from 5: 5 6 4 2 1 0 3
参考答案:
void BFS(ALGraph *G,int i) { int Q[10]; int front=0,rear=0; printf(" %d",i); visited[i]=1; Q[rear++]=i; while(front!=rear) { int now=Q[front++]; ArcNode *p=G->vertices[now].firstarc; while(p) { if(visited[p->adjvex]==0) { printf(" %d",p->adjvex); visited[p->adjvex]=1; Q[rear++]=p->adjvex; } p=p->nextarc; } } }
6-3 拓扑排序
已知课程的先后关系如下表所示:
可用如下有向图表示课程间的关系:
编写函数输出所有课程的拓扑序列。
函数接口定义:
void topsort( ALGraph &G) { int i,v,w; int cnt=0;//计数器初始化为0 EdgeNode *ptr; SeqStack st; InitStack_Sq(st); for(i=0;i
adjvex; __________________________; if(G.adjlist[w].Indegree==0) ____________________; ptr=ptr->next; } } if(cnt 其中
G
为有向图,采用邻接表存储。裁判测试程序样例:
#include
//#include "conio.h" #include #include #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -1 #define MAXSIZE 30 #define VERTEX_MAX 30 /*最大顶点数*/ #define VEX_NUM 10 typedef int Status; typedef char Vextype[20]; /*顶点类型*/ typedef int ElemType; typedef struct { ElemType elem[MAXSIZE]; int top; }SeqStack; /*定义顺序栈结构*/ typedef struct node /*边结点定义*/ { int adjvex; /*邻接点域*/ struct node *next; /*指向下一个边结点的指针域*/ }EdgeNode; typedef struct vnode /*表头结点定义*/ { int Indegree; /*顶点入度域*/ Vextype vertex; /*顶点信息*/ EdgeNode *firstedge; }VertexNode; typedef struct /*图的邻接表存储*/ { VertexNode adjlist[VERTEX_MAX]; int n,e; /*顶点数和边数*/ } ALGraph; void InitStack_Sq(SeqStack &s) /*初始化栈操作*/ {s.top=-1; }/*InitStack_sq*/ int Empty_Sq(SeqStack s) /*判栈是否为空*/ {if(s.top==-1) return 1; else return 0; }/*Empty_sq*/ Status Push_SeqStack(SeqStack &s, ElemType x) {if (s.top==MAXSIZE-1) return OVERFLOW ; /* 栈满不能入栈 */ else { s.top++; s.elem[s.top]=x ; return OK; } } Status Pop_SeqStack(SeqStack &s, ElemType &y) { if (Empty_Sq(s)) return OVERFLOW; /* 栈空不能出栈 */ else { y=s.elem[s.top]; s.top--; return OK; } /* 栈顶元素存入*y,返回 */ } void CreateALGraph(ALGraph &G) /*创建有向图的邻接表*/ { int i,v,w; int Indegree[VERTEX_MAX]={0}; EdgeNode *s; scanf("%d,%d",&(G.n),&(G.e)); /*输入顶点数n和弧数m*/ for (i=0;i adjvex=v; Indegree[v]++; /*统计各顶点的入度*/ s->next=G.adjlist[i].firstedge; /*前插方法*/ G.adjlist[i].firstedge=s; } for(i=0;i 输入样例1:
6,5 高等数学 计算机导论 C语言 英语 数据结构 数据库 0,2 1,2 1,5 2,3 3,4
输出样例1:
拓扑序列为:计算机导论 数据库 高等数学 C语言 英语 数据结构
输入样例2:
6,6 C1 C2 C3 C7 C12 C13 0,2 1,2 1,5 2,3 3,4 4,1
输出样例2:
拓扑序列为:C1 后续无法输出!
参考答案:
void topsort( ALGraph &G) { int i,v,w; int cnt=0;//计数器初始化为0 EdgeNode *ptr; SeqStack st; InitStack_Sq(st); for(i=0;i
adjvex; G.adjlist[w].Indegree--; if(G.adjlist[w].Indegree==0) Push_SeqStack(st,w); ptr=ptr->next; } } if(cnt