数据结构实验八 图及其应用
实验内容
1.编写一个程序,完成如下功能:
(1) 建立如下有向图G1的邻接矩阵输出,并由邻接矩阵产生邻接表输出之; (2) 输出图G1从顶点0开始的深度优先遍历序列; (3) 输出图G1从顶点0开始的广度优先遍历序列; (4) 用普里姆算法输出从顶点0出发的最小生成树;
参考自:https://blog.csdn.net/chj65/article/details/103935951
#include <stdio.h>
#include <iostream>
using namespace std;
typedef int InfoType;
#define MAXV 100
#define INF 32767
typedef struct
{
int no;
InfoType info;
} VertexType;
typedef struct
{
int edges[MAXV][MAXV];
int n, e;
VertexType vexs[MAXV];
} MGraph;
typedef struct ANode
{
int adjvex;
struct ANode* nextarc;
InfoType info;
} ArcNode;
typedef int Vertex;
typedef struct Vnode
{
Vertex data;
ArcNode* firstarc;
} VNode;
typedef VNode AdjList[MAXV];
typedef struct
{
AdjList adjlist;
int n, e;
} ALGraph;
void MatToList1(MGraph g, ALGraph *&G)
{
int i, j;
ArcNode* p;
G = new ALGraph;
for (i = 0; i < g.n; i++)
G->adjlist[i].firstarc = NULL;
for (i = 0; i < g.n; i++)
for (j = g.n - 1; j >= 0; j--)
if (g.edges[i][j] != 0 && g.edges[i][j] != INF)
{
p = new ArcNode;
p->adjvex = j;
p->info = g.edges[i][j];
p->nextarc = G->adjlist[i].firstarc;
G->adjlist[i].firstarc = p;
}
G->n = g.n; G->e = g.e;
}
void DispMat1(MGraph g)
{
int i, j;
for (i = 0; i < g.n; i++)
{
for (j = 0; j < g.n; j++)
if (g.edges[i][j] == INF)
printf("%3s", "∞");
else
printf("%3d", g.edges[i][j]);
cout << endl;
}
}
void DispAdj1(ALGraph* G)
{
int i;
ArcNode* p;
for (i = 0; i < G->n; i++)
{
p = G->adjlist[i].firstarc;
printf("%3d: ", i);
while (p != NULL)
{
printf("%3d(%d)", p->adjvex, p->info);
p = p->nextarc;
}
cout << endl;
}
}
int visited[MAXV] = { 0 };
void DFS(ALGraph* G, int v)
{
ArcNode* p;
visited[v] = 1;
printf("%3d", v);
p = G->adjlist[v].firstarc;
while (p != NULL)
{
if (visited[p->adjvex] == 0)
DFS(G, p->adjvex);
p = p->nextarc;
}
}
void BFS(ALGraph* G, int v)
{
ArcNode* p;
int queue[MAXV], front = 0, rear = 0;
int visited[MAXV];
int w, i;
for (i = 0; i < G->n; i++) visited[i] = 0;
printf("%3d", v);
visited[v] = 1;
rear = (rear + 1) % MAXV;
queue[rear] = v;
while (front != rear)
{
front = (front + 1) % MAXV;
w = queue[front];
p = G->adjlist[w].firstarc;
while (p != NULL)
{
if (visited[p->adjvex] == 0)
{
printf("%3d", p->adjvex);
visited[p->adjvex] = 1;
rear = (rear + 1) % MAXV;
queue[rear] = p->adjvex;
}
p = p->nextarc;
}
}
cout << endl;
}
void Prim(MGraph g, int v)
{
int lowcost[MAXV], min, n = g.n;
int closest[MAXV], i, j, k;
for (i = 0; i < g.n; i++)
{
closest[i] = v;
lowcost[i] = g.edges[v][i];
}
for (i = 1; i < g.n; i++)
{
min = INF;
for (j = 0; j < g.n; j++)
{
if (lowcost[j] != 0 && lowcost[j] < min)
{
min = lowcost[j];
k = j;
}
}
printf("边(%d,%d)权为:%d\n", closest[k], k, min);
lowcost[k] = 0;
for (j = 0; j < g.n; j++)
{
if (g.edges[k][j] != 0 && g.edges[k][j] < lowcost[j])
{
lowcost[j] = g.edges[k][j];
closest[j] = k;
}
}
}
}
int main()
{
ALGraph* G;
MGraph g;
int path[MAXV], i, j, v = 0;
g.n = 6; g.e = 10;
int A[MAXV][6] = {
{ 0, 5, INF, 7, INF, INF },
{ INF, 0, 4, INF, INF, INF },
{ 8, INF, 0, INF, INF, 9 },
{ INF, INF, 5, 0, INF, 6 },
{ INF, INF, INF, 5, 0, INF },
{ 3, INF, INF, INF, 1, 0 } };
for (i = 0; i < g.n; i++)
for (j = 0; j < g.n; j++)
g.edges[i][j] = A[i][j];
cout << "有向图G的邻接矩阵:" << endl;
DispMat1(g);
G = new ALGraph;
MatToList1(g, G);
cout << "图G的邻接表:" << endl;
DispAdj1(G);
cout << "从顶点0开始的DFS(递归算法):" << endl;
DFS(G, 0);
cout << endl;
cout << "从顶点0开始的BFS(非递归算法):" << endl;
BFS(G, 0);
cout << endl;
cout << "普里姆算法求解结果:" << endl;
Prim(g, 0);
return 0;
}
2.基于Dijkstra算法的最短路径求解:
问题描述:
一张地图包括n个城市,假设城市间有m条路径(有向图),每条路径的长度已知。给定地图的一个起点城市和终点城市,利用Dijsktra算法求出起点到终点之间的最短路径。
输入要求:
多组数据,每组数据有m+3行。第一行为两个整数n和m,分别代表城市个数n和路径条数m。第二行有n个字符,代表每个城市的名字。第三行到第m+2行每行有两个字符a和b和一个整数d,代表从城市a到城市b有一条距离为d的路径。最后一行为两个字符,代表待求最短路径的城市起点和终点。当n和m都等于0时,输入结束。
输出要求:
每组数据输出两行。第一行为一个整数,为从起点到终点之间最短路径的长度。第二行为一串字符串,代表该路径。每两个字符之间用空格隔开。
输入样例
3 3
A B C
A B 1
B C 1
C A 3
A C
6 8
A B C D E F
A F 100
A E 30
A C 10
B C 5
C D 50
D E 20
E F 60
D F 10
A F
0 0
输出样例
2
A B C
60
A E D F
#include<iostream>
using namespace std;
#define maxn 200
#define inf 1e9
int n;
char v[maxn];
int Hash[maxn];
int e[maxn][maxn];
int dis[maxn];
int path[maxn];
int visit[maxn];
void Dijkstra(int x)
{
int k, min;
for (int i = 1; i <= n; i++)
{
dis[i] = e[x][i];
visit[i] = 0;
if (e[x][i] < inf)
path[i] = x;
else
path[i] = -1;
}
dis[x] = 0;
visit[x] = 1;
for (int t = 0; t < n - 1; t++)
{
min = inf;
for (int i = 1; i <= n; i++)
{
if (!visit[i] && dis[i] < min)
{
k = i;
min = dis[i];
}
}
visit[k] = 1;
for (int i = 1; i <= n; i++)
{
if (!visit[i] && dis[i] > dis[k] + e[k][i])
{
dis[i] = dis[k] + e[k][i];
path[i] = k;
}
}
}
}
void printpath(int x)
{
if (x != -1)
{
printpath(path[x]);
cout << v[x] << " ";
}
}
int main()
{
int m, d;
char x, y;
while (1)
{
cin >> n >> m;
if (!n && !m)break;
for (int i = 0; i < maxn; i++)
for (int j = 0; j < maxn; j++)
e[i][j] = inf;
for (int i = 1; i <= n; i++)
{
cin >> v[i];
Hash[v[i]] = i;
}
while (m--)
{
cin >> x >> y >> d;
e[Hash[x]][Hash[y]] = e[Hash[y]][Hash[x]] = d;
}
cin >> x >> y;
Dijkstra(Hash[x]);
cout << dis[Hash[y]] << endl;
printpath(path[Hash[y]]);
cout << v[Hash[y]] << endl;
}
return 0;
}
|