作为城市的紧急救援团队负责人,你将获得一张你所在国家的特殊地图。
该地图显示了一些通过道路连接的分散城市,道路是双向的。
地图上标出了每个城市的救援队数量以及每对城市之间的每条道路的长度。
当其他城市发出紧急求援信息时,你的工作是尽快带领你的士兵前往该地点,同时,在途中尽可能多地调动救援帮手。
输入格式
第一行包含四个整数 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
d[v]=d[u]+w 时,证明走的是"最短路";d[v]>d[u]+w 时,证明 0-v 不是最短路
不太懂错哪了…
#include
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;
}
复杂度分析