给定无向图,求起点到终点最短路条数,以及最短路中点权最大值。
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 500 + 5;
typedef pair<int, int> pr;
struct edge{
int u,v,w;
};
vector<edge> es;
vector<int> mp[maxn];
int city[maxn];
bool vis[maxn];
int d[maxn];
int n,m,S,T;
int sum[maxn];
void addedge(int u,int v,int w)
{
es.push_back({u,v,w});
es.push_back({v,u,w});
int m = es.size();
mp[u].push_back(m - 2);
mp[v].push_back(m - 1);
}
void dij(int s)//从终点开始
{
priority_queue<pr,vector<pr>,greater<pr> > pq;
memset(vis, 0, sizeof(vis));
memset(d, -1, sizeof(d));
d[s] = 0;
pq.push({d[s],s});
while (!pq.empty()) {
pr p = pq.top();pq.pop();
int x = p.second;
if(vis[x]) continue;
vis[x] = 1;
for (int i = 0; i < mp[x].size(); i ++) {
edge &e = es[mp[x][i]];
if(d[e.v] == -1 || d[e.v] > d[e.u] + e.w){
d[e.v] = d[e.u] + e.w;
sum[e.v] = city[e.v] + sum[e.u];
pq.push({d[e.v],e.v});
}
else if(d[e.v] == d[e.u] + e.w && sum[e.v] < city[e.v] + sum[e.u]){
sum[e.v] = city[e.v] + sum[e.u];
pq.push({d[e.v],e.v});
}
}
}
}
int num[maxn];
int dfs(int u)//应该是记忆化搜索,计算最短路条数
{
if(u == T) return num[u] = 1;
int ans = 0;
for (int i =0 ; i < mp[u].size(); i ++) {
edge &e = es[mp[u][i]];
if(d[u] == d[e.v] + e.w){
if(vis[e.v]) ans += num[e.v];
else{
vis[e.v] = 1;
ans += dfs(e.v);
}
}
}
return num[u] = ans;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&S,&T);
for (int i =0 ; i < n; i ++) {
scanf("%d",&city[i]);
}
int u,v,w;
for (int i = 0; i < m; i ++) {
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
dij(T);
memset(vis, 0, sizeof(vis));
memset(num, 0, sizeof(num));
dfs(S);
printf("%d %d\n",num[S],sum[S] + city[T]);
return 0;
}