【图论】B067_AW_紧急情况(最短路计数+扩展)

图论 专栏收录该内容
71 篇文章 0 订阅

作为城市的紧急救援团队负责人,你将获得一张你所在国家的特殊地图。

该地图显示了一些通过道路连接的分散城市,道路是双向的。

地图上标出了每个城市的救援队数量以及每对城市之间的每条道路的长度。

当其他城市发出紧急求援信息时,你的工作是尽快带领你的士兵前往该地点,同时,在途中尽可能多地调动救援帮手。

输入格式
第一行包含四个整数 N,表示城市数量(城市编号从 0 到 N−1),M 表示道路数量,C1 表示你当前所在的城市编号,C2 表示发出紧急求援信息的城市编号。
第二行包含 N 个整数,其中第 i 个整数表示城市 i 的救援队数量。
接下来 M 行,每行包含三个整数 c1,c2,Li,表示城市 c1 和城市 c2 之间存在一条道路相连,道路长度为 Li。
数据保证 C1 和 C2 之间至少存在一条路径相连。
输出格式
共一行,两个整数,第一个整数表示 C1 和 C2 之间最短路的数量,第二个整数表示走最短路的情况下,能聚集到的救援队最大数量。
数据范围
2≤N≤500,
1≤M≤600,
1≤Li≤200,
每个城市包含的救援人员数量不超过 200。

输入样例:
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
输出样例:
2 4
方法一:spfa

在这里插入图片描述
d[v]=d[u]+w 时,证明走的是"最短路";d[v]>d[u]+w 时,证明 0-v 不是最短路

不太懂错哪了…

#include<bits/stdc++.h>
using namespace std;
const int N=1e4, inf=0x3f3f3f3f;
int n,m,s,e,d[N],c[N],inq[N],team[N],mteam[N];
struct node {
    int u,w;
};
vector<node> g[N];
void spfa() {
    memset(d, inf, sizeof d), memset(inq, false, sizeof inq), memset(c, 0, sizeof c);
    queue<int>q; q.push(s), d[s]=0, c[s]=1;

    while (!q.empty()) {
        int u=q.front(); q.pop(), inq[u]=false;
        for (auto& nx : g[u]) {
            int v=nx.u, w=nx.w;
            if (d[v]>d[u]+w) {
                if (!inq[v]) {
                    q.push(v), inq[v]=true;
                }
                d[v]=d[u]+w, c[v]=c[u];
                mteam[v]=mteam[u]+team[v];
            } else if (d[v]==d[u]+w){
                c[v]+=c[u];
                mteam[v]=max(mteam[v], mteam[u]+team[v]);
            }
        }
    }
}
int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>s>>e;
    for (int i=0; i<n; i++) cin>>team[i], mteam[i]=team[i];
    for (int i=0; i<m; i++) {
        int u,v,w; cin>>u>>v>>w;
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }
    spfa();
    cout << c[e] << ' ' << mteam[e];
    return 0;
}

复杂度分析

  • Time O ( ( n + m ) l o g n ) O((n+m)logn) O((n+m)logn)
  • Space O ( n ) O(n) O(n)
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

wdt_

倘若小文于你有益,欢迎小额赞赏

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值