图的邻接矩阵表示和Floyd算法都是贴模板然后再改一改
重点在于找到那只动物
原理很简单,如果有一只动物变成所有其他动物的代价中最大代价最小,那么就带这只动物
#include <iostream>
using namespace std;
/*--------------------------图的邻接矩阵表示法--------------------------*/
// 直接复制模板, 再加以修改
#define MaxVertexNum 100 /* 最大顶点数设为100 */
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex; /* 用顶点下标表示顶点, 为整型 */
typedef int WeightType; /* 边的权值设为整型 */
// typedef char DataType; /* 顶点存储的数据类型设为字符型 */
/* 边的定义 */
typedef struct ENode *PtrToENode;
struct ENode {
Vertex V1, V2; /* 有向边<V1, V2> */
WeightType Weight; /* 权重 */
};
typedef PtrToENode Edge;
/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode {
int Nv; /* 顶点数 */
int Ne; /* 边数 */
WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
// DataType Data[MaxVertexNum]; /* 存顶点的数据 */
// /* 注意:很多情况下,顶点无数据,此时Data[]可以不用出现 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
/* 初始化一个有VertexNum个顶点但没有边的图 */
MGraph CreateGraph( int VertexNum ) {
Vertex V, W;
MGraph Graph;
Graph = new GNode; /* 建立图 */
Graph->Nv = VertexNum;
Graph->Ne = 0;
/* 初始化邻接矩阵 */
/* 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1) */
for (V=0; V<Graph->Nv; V++)
for (W=0; W<Graph->Nv; W++)
Graph->G[V][W] = INFINITY;
return Graph;
}
void InsertEdge( MGraph Graph, Edge E ) {
/* 插入边 <V1, V2> */
Graph->G[E->V1][E->V2] = E->Weight;
/* 若是无向图,还要插入边<V2, V1> */
Graph->G[E->V2][E->V1] = E->Weight;
}
MGraph BuildGraph() {
MGraph Graph;
Edge E;
// Vertex V;
int Nv, i;
cin >> Nv; /* 读入顶点个数 */
Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */
cin >> Graph->Ne; /* 读入边数 */
if ( Graph->Ne != 0 ) { /* 如果有边 */
E = new ENode; /* 建立边结点 */
/* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */
for ( i=0; i < Graph->Ne; i++ ) {
cin >> E->V1 >> E->V2 >> E->Weight;
/* 注意:如果权重不是整型,Weight的读入格式要改 */
E->V1--; // 起始编号从0开始
E->V2--;
InsertEdge( Graph, E );
}
}
// /* 如果顶点有数据的话,读入数据 */
// for (V=0; V<Graph->Nv; V++)
// cin >> Graph->Data[V];
return Graph;
}
/*------------------------------Floyd算法------------------------------*/
/* 邻接矩阵存储 - 多源最短路算法 */
// 贴模板修改
void Floyd( MGraph Graph, WeightType D[][MaxVertexNum] /*, Vertex path[][MaxVertexNum] */ ) {
Vertex 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; /* 算法执行完毕,返回正确标记 */
}
WeightType findMaxDist( WeightType D[][MaxVertexNum], Vertex i, int N ) {
WeightType maxDist = 0;
for( int j = 0; j < N; j++ )
if( i != j && D[i][j] > maxDist )
maxDist = D[i][j];
return maxDist;
}
void findAnimal( MGraph gragh ) {
WeightType D[MaxVertexNum][MaxVertexNum], maxDist, minDist;
Vertex Animal; // 动物编号
Floyd(gragh, D);
/* 从每个动物i的最短距离的最大值中, 找到最小值minDist, 以及对应的动物Animal */
minDist = INFINITY;
for( int i = 0; i < gragh->Nv; i++ ) {
maxDist = findMaxDist(D, i, gragh->Nv);
if( maxDist == INFINITY ) { // 说明有从i无法变出的动物
cout << "0";
return;
}
if( minDist > maxDist ) { // 找到最长距离更小的动物
minDist = maxDist;
Animal = i + 1; // 更新距离, 记录编号(从1开始编号)
}
}
cout << Animal << " " << minDist;
}
int main() {
MGraph G = BuildGraph(); // 邻接矩阵
findAnimal(G);
return 0;
}