<Sicily>Catch the thief

一、题目描述

A thief has robbed a bank in city 1 and he wants to go to city N. The police know that the thief will choose the shortest path to get to his destination. As there may be multiple shortest paths, the police want to calculate the number of all the cities that the thief may visit. (Including city 1 and city N)

二、输入

The input may contain several test cases.

Each test case starts with a line containing an integer N, indicating the number of cities.

The next N lines describe a N*N matrix A. the jth element in the ith row indicates the distance between city i and city j is Aij (Aij=Aji). Aij=-1 means city i and city j is not connected.

N=0 indicates the end of the input.

三、输出

For each test case, just print the total number of the cities the thief may visit in a single line.

例如:
输入:
5
0 1 4 -1 -1
1 0 -1 2 -1
4 -1 0 -1 2
-1 2 -1 0 3
-1 -1 2 3 0
0
输出:
5

四、解题思路

题意:
从起点0,到终点n,可能有多条最短路径,找出这些路径可能经过的节点。

这道题开始不知道怎么入手。有同学提醒说,求起点到各点的最短路径,终点到个点的最短路径,再取交点。

原理:起点0,终点n,假设点领到点n的最短路径长度为shortDis。判断是否有最短路径经过点1。点0到点1的最短路径为shortDisMatrix[0][1],点1到点n的最短路径为shortDisMatrix[1][n]。如果shortDisMatrix[0][1] + shortDisMatrix[1][n]==shortDis,那么有最短路径经过点1;同样使用这种方法判断其他点。

附:使用弗洛伊德算法求某点到其他各点的最短路径。

五、代码

#include<iostream>

using namespace std;

const int MAX_DIS = 500;
const int MAX_CITY_COUNT = 500;

int main()
{
    int cityCount;
    while(cin >> cityCount && cityCount > 0)
    {

        int disMatrix[MAX_CITY_COUNT][MAX_CITY_COUNT] = {0};    //保存个点距离

        int distance;
        for(int i = 0; i < cityCount; i++)
        {
            for(int j = 0; j < cityCount; j++)
            {
                cin >> distance;
                if(distance < 0) {distance = MAX_DIS;}
                disMatrix[i][j] = distance;
            }
        }

        for(int i = 0; i < cityCount; i++)      //使用Floyd算法求最短路劲
        {
            for(int j = 0; j < cityCount; j++)
            {
                for(int n = 0; n < cityCount; n++)
                {
                    if(disMatrix[j][n] > disMatrix[j][i] + disMatrix[i][n])
                        disMatrix[j][n] = disMatrix[j][i] + disMatrix[i][n];
                }
            }
        }
        int result = 2;

        for(int i = 1; i < cityCount - 1; i++)  //判断i点是否有(起点到终点)最短路径经过
        {
            if((disMatrix[0][i] + disMatrix[i][cityCount - 1]) == disMatrix[0][cityCount - 1]) result++;
        }

        cout << result << endl;
    }

    return 0;
}
<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值