PAT甲级1003

本文代码参考柳神代码,作者修改了一点,加了很多备注,方便理解。

// 1003_Emergency.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <algorithm>
using namespace std;
int n, m, c1, c2;
int e[501][501], weight[501], dis[501],num[501], w[501];//这里的数组为全局变量,默认数组元素值初始化为0
constexpr int inf = 999;//恒定义inf值为999,此处用constexpr 指明inf是一个常量。const常用来表达变量只读
bool visit[501];//定义全局bool型数组visit,数组中默认元素全为false

int main()
{
    //已知数据录入
    scanf_s("%d%d%d%d", &n, &m, &c1, &c2);
    for (int i = 0; i < n; i++)
    {
        scanf_s("%d", &weight[i]);
    }
    /* fill(e[0], e[0] + 501 * 501, inf);//fill函数初始化两个数组
    fill(dis, dis + 501, inf);*/
    fill_n(&e[0][0], 501 * 501, inf);//使用fill_n函数初始化二维数组e[501][501]
    fill_n(dis, 501, inf);//使用fill_n函数初始化一维数组dis[501]
    
    int a, b, c;
    for (int i = 0; i < m; i++)//城市之间的距离数据录入
    {
        scanf_s("%d%d%d", &a, &b, &c);
        e[a][b] = e[b][a] = c;
    }
    dis[c1] = 0;//c1到c1的距离为0
    num[c1] = 1;//此处写下这条语句,另一顶点c2到c1的最短路径如有n条。则num[c2]=n*num[c1];//num[c2]=0;
    w[c1] = weight[c1];//c1为起点,起点的权重为该城市救援队的数量
    for (int i = 1; i < n; i++)//进入主循环,i从1开始,因为w0到w0的最短距离无需计算
    {
        int u = -1;
        int minn = inf;//设置初始最短路径为minn,即999
        for (int j = 0; j < n; j++)//通过此循环找到离顶点c1最近的顶点。visit[c1] = 1,故此处跳过点c1自己
        {
            if (visit[j] == false && dis[j] < minn)
            {
                u = j;
                minn = dis[j];
            }
        }
        printf("第%d轮,u的值为%d\n", i, u);
        visit[u] = true;//将visit[u]置1,已找到距离顶点c1最近的点u
        for (int v = 0; v < n; v++)
        {
            if (visit[v] == false && e[u][v] != inf)
            {
                if (dis[u] + e[u][v] < dis[v])//如果新距离小于原最短距离,则更新最短距离。
                {
                    dis[v] = dis[u] + e[u][v];/*更新最短距离*/
                    num[v] = num[u];/*更新最短路径条数(num更新为距离最短的路径条数)*/
                    w[v] = w[u] + weight[v];/*更新权重*/
                    printf("第%d轮的第%d小轮,dis[%d]已更新为%d,w[%d]已更新为%d\n",i,v,v,dis[v],v,w[v]);
                }
                else if (dis[u] + e[u][v] == dis[v])//如果多条最短距离相等,则增加最短距离条数。
                {
                    num[v] = num[v] + num[u];/*更新最短路径条数(num更新为距离相等的最短路径条数相加)*/
                    if (w[u] + weight[v] > w[v])//判断距离相等且走法不同的最短路径上的救援小组数目大小,输出救援小组数目最大的那组
                        w[v] = w[u] + weight[v];//更新权重
                    printf("第%d轮的第%d小轮,%d到%d最短路径条数已更新,w[%d]已更新为%d\n", i,dis[v],c1,v, v, w[v]);
                }
            }
        }
        printf("-----------------------------------------------------\n");
    }
    printf("%d %d", num[c2], w[c2]);
    return 0;
}

附:
1003题已知信息罗列:
共有5个城市(0号城市到4号城市)
城市间有6条路
目前处于0号城市,需要赶往2号城市。
0号城市:1支救援队
1号城市:2支救援队
2号城市:1支救援队
3号城市:5支救援队
4号城市:3支救援队
0号城市到1号城市:距离为1
0号城市到2号城市:距离为2
0号城市到3号城市:距离为1
1号城市到2号城市:距离为1
2号城市到4号城市:距离为1
3号城市到4号城市:距离为1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值