哈利·波特的考试

  • 题目来源:

浙江大学在慕课网上开设的《数据结构》课,陈越老师、何钦铭老师主讲,课后作业的一道题。

  • 题目描述

  • 题目思路:

这个题目是求图中“每一对顶点之间的最短路径”,应用到的算法是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;
}
posted @ 2019-08-20 16:54  尚修能的技术博客  阅读(354)  评论(0编辑  收藏  举报