导游 解题报告(Floyd-Warshall 算法)

来源:互联网 发布:如何把excel导入mysql 编辑:程序博客网 时间:2024/06/11 15:45

导游 解题报告(Floyd-Warshall 算法)

Description
Mr. G. 在孟加拉国的一家旅游公司工作。他当前的任务是带一些游客去一些遥远的城市。和所有国家一样,一些城市之间有双向道路。每对相邻城市之间都有一条公交路线,每条路线都规定了自己的最大乘客数目。Mr. G. 有一份包含城市间道路状况和公交车最大载客量的地图。
往往无法一次性地将所有乘客带往目的地。例如,在下面7个城市的地图中,边代表道路,每条边上的数字代表这条道路上公交车的最大载客量。

如果Mr. G. 要将99位乘客从城市1带到城市7,则至少要往返5次(他必须陪同每一群乘客)。最佳路线是1-2-4-7。

初始: 1(99) 2(0) 4(0) 7(0)

第1次往返后:1(75) 2(0) 4(0) 7(24)

第2次往返后:1(51) 2(0) 4(0) 7(48)

第3次往返后:1(27) 2(0) 4(0) 7(72)

第4次往返后:1(3) 2(0) 4(0) 7(96)

第5次往返后:1(0) 2(0) 4(0) 7(99)

Input
第一行为一个整数t,表示测试用例个数。 每组数据的第一行有两个整数N(N≤100)和R(R≤4950),分别表示城市的数量和道路的数量。接下来的R行每行有3个整数(C1,C2,P),其中C1和C2为城市编号,P(1

#include <iostream>#include <algorithm>#include <stdlib.h>using namespace std;#define MAX_VEX_NUM 100int Matrix[MAX_VEX_NUM][MAX_VEX_NUM];int main(){    int T;    cin >> T;    while (T--)    {        int N, R;        cin >> N >> R;        //对矩阵进行初始化        for (int i = 1;i <= N;i++)            for (int j = 1;j <= N;j++)                Matrix[i][j] = 0;        //通过输入构造矩阵        while (R--)        {            int C1, C2, P;            cin >> C1 >> C2 >> P;            Matrix[C1][C2] = Matrix[C2][C1] = P;        }        //Floyid-warshall算法        //Matrix[i][j]表示从i到j的路径中的最小乘客数        for (int k = 1;k <= N;k++)//如能通过中间节点k从i到达j,初始化Matrix[i][j]            for (int i = 1;i <= N;i++)                for (int j = 1;j <= N;j++)                    Matrix[i][j] = max(Matrix[i][j], min(Matrix[i][k], Matrix[k][j]));        int S, D, T;        cin >> S >> D >> T;        cout << Matrix[S][D] << endl;        cout << T / (Matrix[S][D] - 1) + (T % (Matrix[S][D] - 1) ? 1 : 0) << endl;    }    return 0;}

本题中主要运用了Floyid算法,这种算法常用于求最短路径问题。本题虽然不是最短路径问题,但思路是一样的。值得注意的是:

        for (int k = 1;k <= N;k++)//如能通过中间节点k从i到达j,初始化Matrix[i][j]            for (int i = 1;i <= N;i++)                for (int j = 1;j <= N;j++)                    Matrix[i][j] = max(Matrix[i][j], min(Matrix[i][k], Matrix[k][j]));

这种算法中的中间节点的遍历要放在最前面。
理解:k从1开始,找出所有能够通过k从i到j的路径,并赋值给Matrix[i][j],相当于此时形成了i到j的新通路;然后对新的图的每对节点,看看能不能通过k这个中间节点找到i到j的新通路,找到则赋值,当然,每形成一个新的通路要跟原来已有的通路进行比较,将较优值赋予该节点对的路径长。

1 0
原创粉丝点击