哈利·波特的考试
- 题目来源:
浙江大学在慕课网上开设的《数据结构》课,陈越老师、何钦铭老师主讲,课后作业的一道题。
- 题目描述
- 题目思路:
这个题目是求图中“每一对顶点之间的最短路径”,应用到的算法是Floyd算法。
- C语言实现:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxVerterNum 101 //最大定点数设为100
#define INFINITY 65535 //无穷设为双字节无符号整数的最大值65535
typedef int WeightType; //边的权值设为int类型
typedef char DataType; //顶点存储的数据类型设置为字符类型
typedef int Vertex; //用顶点下标表示顶点,为整型
struct GNode
{
int Nv; //顶点数
int Ne; //边数
WeightType G[MaxVerterNum][MaxVerterNum]; //邻接矩阵
DataType Data[MaxVerterNum][MaxVerterNum]; //存顶点的数据
/*如果顶点无数据,此时Data[]可以不出现*/
};
//描述边的类型
struct ENode
{
Vertex V1, V2; //有向边<V1,V2>
WeightType Weight; //权重
};
//作用:初始化一个有VertexNum个顶点但没有边的图
struct GNode* CreateGraph(int VertexNum)
{
Vertex V, W;
struct GNode* Graph;
Graph = (struct GNode*)malloc(sizeof(struct GNode)); //建立图
Graph->Nv = VertexNum;
Graph->Ne = 0;
//初始化邻接矩阵
for (V = 0; V < Graph->Nv; V++)
{
for (W = 0; W < Graph->Nv; W++)
{
Graph->G[V][W] = INFINITY;
}
}
for (V = 0; V < Graph->Nv; V++)
{
for (W = 0; W < Graph->Nv; W++)
{
if (V == W)
{
Graph->G[V][W] = 0; //对角线初始化为0
break;
}
}
}
return Graph;
}
//作用:在图中插入边
void InsertEdge(struct GNode* Graph, struct ENode* E)
{
////插入边<V1,V2>
Graph->G[E->V1][E->V2] = E->Weight;
////若是无向图,还需要插入<V2,V1>
Graph->G[E->V2][E->V1] = E->Weight;
////插入边<V1,V2>
//Graph->G[E->V1][E->V2] = 1;
////若是无向图,还需要插入<V2,V1>
//Graph->G[E->V2][E->V1] = 1;
}
//作用:构建一个图,供主函数调用
struct GNode* BulidGraph()
{
Vertex V;
int NV;
struct ENode* E;
struct GNode* Graph;
scanf("%d", &NV); //读入顶点个数
Graph = CreateGraph(NV);
scanf("%d", &(Graph->Ne)); //读入边数
if (Graph->Ne != 0)
{
E = (struct ENode*)malloc(sizeof(struct ENode));
for (int i = 0; i < Graph->Ne; i++)
{
//如果权重不是整型,Weight的读入格式要改
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
E->V1--;
E->V2--;
InsertEdge(Graph, E);
}
}
////如果顶点有数据的话,读入数据
//for (V = 0;V < Graph->Nv;V++)
//{
// scanf("%c",&(Graph->Data[V]));
//}
return Graph;
}
//作用:Floyd算法
//参数:struct GNode* Graph 图
// WeightType D[][MaxVerterNum] 最短路径长度
// Vertex path[][MaxVerterNum] 最短路径
bool Floyd(struct GNode* Graph,WeightType D[][MaxVerterNum],Vertex path[][MaxVerterNum])
{
int i, j, k;
for (i = 0;i < Graph->Nv;i++)
{
for (j = 0;j < Graph->Nv;j++)
{
D[i][j] = Graph->G[i][j];
path[i][j] = -1;
}
}
for (k = 0;k < Graph->Nv;k++)
{
for (i = 0; i < Graph->Nv; i++)
{
for (j = 0; j < Graph->Nv; j++)
{
if (D[i][k] + D[k][j] < D[i][j])
{
D[i][j] = D[i][k] + D[k][j];
if (i == j && D[i][j] < 0) //若发现负值圈
{
return false;
}
path[i][j] = k;
}
}
}
}
return true;
}
int main()
{
int result = INFINITY;
int Animal = 0;
struct GNode* Graph = BulidGraph();
WeightType D[MaxVerterNum][MaxVerterNum];
Vertex path[MaxVerterNum][MaxVerterNum];
if (Floyd(Graph,D,path))
{
int temp = 0;
for (int i = 0;i < Graph->Nv;i++)
{
for (int j = 0;j < Graph->Nv;j++)
{
if (D[i][j] == INFINITY)
{
printf("0");
return 0;
}
if (D[i][j] > temp)
{
temp = D[i][j];
}
}
if (temp < result)
{
result = temp;
Animal = i;
}
temp = 0;
}
}
printf("%d %d\n",Animal + 1,result);
// system("pause");
return 0;
}