POJ2139 Six Degrees of Cowvin Bacon(最短路径)

一、题目大意

有N头牛,参与拍摄了M部电影。

如果两头牛,例如牛1和牛2,一起拍摄过电影,则两头牛之间的关系值是1,即 牛1 <-> 牛2。

如果牛1和牛3没有一起拍过电影,但牛1和牛2拍过电影,牛2和牛3也拍过,那就可以理解为牛1和牛3的关系值为2,即:牛1 <-> 牛2 <-> 牛3。

因此不难想出,每头牛是一个节点,每条边长度是1,我们知道哪些点之间有边。

题目中需求出的是,哪个点到达其他所有点的距离之和平均值最小。

二、解题思路

在本题目中,可以先根据输入构建出图,然后利用warshallFloyd算法,求出任意两头牛之间的距离,然后遍历所有的牛,分别计算它与其他牛之间的距离之和,作比较来求出与其他牛最近综合最小的牛,并计算出距离之和的平均值。

本题的输入为N,M,代表牛的数量和电影的数量,之后的M行,每一行列出的是一部电影的相关信息,即参演的牛的数量和参演的牛有哪些,因此我们可以定义一个数组和一个对应的count用来记录一部电影的信息。

//存放参演某部电影的牛的ID信息的数组
int movieCowIdArray[MAX_COW_COUNT];
//存放参演某部电影的牛的数量的信息
int movieCowCount;

然后,根据每一部电影的信息,来构建部分的图。

void buildGraphByOneMovie() {
	//一起参演的两头牛之间的距离为1,自己和自己的距离一定是0
	for(int i=0; i

根据电影的数量循环,来构建出整个图。

void getInputData() {
	for(int i=0; i

warshallFloyd算法

void warshall_floyd() {
	for(int k=1; k<=cowCount; k++) {
		for(int i=1; i<=cowCount; i++) {
			for(int j=1; j<=cowCount; j++) {
				if(distanceBetweenTwoCows[i][j]>distanceBetweenTwoCows[i][k]+distanceBetweenTwoCows[k][j]) {
					distanceBetweenTwoCows[i][j]=distanceBetweenTwoCows[i][k]+distanceBetweenTwoCows[k][j];
				}
			}
		}
	}
}

三、代码

#include 
using namespace std;
//最大的牛的数量
const int MAX_COW_COUNT=309;
//最大的电影数量
const int MAX_MOVIE_COUNT=10009;
//无穷大
const int inf=100000;
//任意两头牛之间的距离
int distanceBetweenTwoCows[MAX_COW_COUNT][MAX_COW_COUNT];
//牛的数量
int cowCount;
//电影的数量
int movieCount;
//获取输入的牛的数量和电影的数量
void getInputCount() {
	scanf("%d%d",&cowCount,&movieCount);
}
//初始化图
void initGraph() {
	//任意两头牛之间的距离初始化为无穷大
	for(int i=1; i<=cowCount; i++) {
		for(int j=1; j<=cowCount; j++) {
			distanceBetweenTwoCows[i][j]=inf;
		}
	}
	//自己和自己之间的距离为0
	for(int i=1; i<=cowCount; i++) {
		distanceBetweenTwoCows[i][i]=0;
	}
}
//存放参演某部电影的牛的ID信息的数组
int movieCowIdArray[MAX_COW_COUNT];
//存放参演某部电影的牛的数量的信息
int movieCowCount;
//获取输入信息
void buildGraphByOneMovie() {
	//一起参演的两头牛之间的距离为1,自己和自己的距离一定是0
	for(int i=0; idistanceBetweenTwoCows[i][k]+distanceBetweenTwoCows[k][j]) {
					distanceBetweenTwoCows[i][j]=distanceBetweenTwoCows[i][k]+distanceBetweenTwoCows[k][j];
				}
			}
		}
	}
}
//计算与其他牛的距离之和
int calculateSumOfDistanceToOtherCows(int cowId) {
	int sumOfDistanceToOtherCows=0;
	for(int i=1; i<=cowCount; i++) {
		sumOfDistanceToOtherCows+=distanceBetweenTwoCows[cowId][i];
	}
	return sumOfDistanceToOtherCows;
}
int main() {
	//获取输入的数量
	getInputCount();
	//初始化图
	initGraph();
	//获取输入的信息并构建图
	getInputData();
	//计算任意两点之间的最短距离
	warshall_floyd();
	//假设第一头牛和其他所有牛的距离之和最短
	int minSumOfDistanceToOtherCows=calculateSumOfDistanceToOtherCows(1);
	for(int cowId=2; cowId<=cowCount; cowId++) {
		//遍历所有的牛,依次求出距离其他牛的距离之和
		int currentSumOfDistanceToOtherCows=calculateSumOfDistanceToOtherCows(cowId);
		//如果距离之和比之前保存的还要小,那就更新为新的距离之和
		if(currentSumOfDistanceToOtherCows

四、总结

在编写代码的过程中,在变量名,方法名和注释上更用心一些,代码的准确性也会有所提高。

你可能感兴趣的:(数据结构,ACM,算法,数据结构)