07-图4 哈利·波特的考试

哈利·波特的考试

图的邻接矩阵表示和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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

低冷dl

喜欢您来~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值