L2-001 紧急救援 (25 分)

原题链接

#include<bits/stdc++.h>
using namespace std;
int cnt[1111];     //最短路径条数
int book[1111];    //各个城市是否经过
int jiu[1111];     //每个城市救援队数量
int jiuyuan[1111]; //到达该城市召集的所有救援队的数量
int pre[1111];     //到达该城市前所经历的编号
int n, m,s,d,u;
int inf = 9999999;
int e[1111][1111];
void dijkstra()
{
    cnt[s]=1;//开始时路径为1;
    book[s]=1;
    for(int i=0;i<n;i++)
    {
        int u=-1,minn=inf;
        for(int j=0;j<n;j++)
        {
            if(book[j]==0&&e[s][j]<minn)
            {
                minn=e[s][j];
                u=j;
            }
        }
       if(u==-1)
       break;
       else
       book[u]=1;//到达下一城市
       for(int j=0;j<n;j++)
       {
           if(book[j]==0&&e[s][j]>e[s][u]+e[u][j])//到达某一城市的最短路径
            //u是中途的那个点;
           {
               e[s][j]=e[s][u]+e[u][j];//更新最短路径
               pre[j]=u;//记录上一个城市编号
               cnt[j]=cnt[u];//拷贝到达上一个城市的最短路径条数;
               jiuyuan[j]=jiuyuan[u]+jiu[j];//能召集的所有救援队数量
           }
           else if(book[j]==0&&e[s][j]==e[s][u]+e[u][j])
           {
               cnt[j]=cnt[j]+cnt[u];
               if(jiuyuan[j]<jiuyuan[u]+jiu[j])
               {
                   pre[j]=u;
                   jiuyuan[j]=jiuyuan[u]+jiu[j];
               }
           }
       }
    }
}
int main()
{
    cin >> n >> m >> s >> d;
    for (int i = 0; i < n; i++)
    {
        cin >> jiu[i];
        jiuyuan[i] = jiu[i];
        cnt[i] = 1;
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (i != j)
                e[i][j] = inf;
        }
    }
    int a, b, c;
    for (int i = 0; i < m; i++)
    {
        cin >> a >> b >> c;
        e[a][b] = c;
        e[b][a] = c;
    }
    dijkstra();
    cout << cnt[d] << " " << jiuyuan[d] + jiu[s] << endl;
    int road[1111];
    int x = 0, t = d;
    while (pre[t] != 0) //所经历的城市从后往前的顺序
    {
        road[x++] = pre[t];
        t = pre[t];
    }
    cout << s;
    for (int i = x - 1; i >= 0; i--)
        cout << " " << road[i];
    cout << " " << d;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值