题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376

这题是传统单DFS算法的应用,直接在更新最短距离那一步把事情都做完。

代码

  1. #include<vector>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<iostream>
  5. using namespace std;
  6. const int maxn = 510;
  7. const int INF = 1000000000;
  8. int n, m, c1, c2;
  9. int temp_c1, temp_c2, temp_d;
  10. int weight[maxn], G[maxn][maxn];
  11. int d[maxn], num[maxn], w[maxn];//d[maxn]是起点到各点的最短距离
  12. bool vis[maxn] = {false};
  13. void Dijkstra(){
  14. fill(d, d + maxn, INF);
  15. fill(w, w + maxn, 0);
  16. fill(num, num + maxn, 0);
  17. d[c1] = 0;
  18. w[c1] = weight[c1];
  19. num[c1] = 1;
  20. for(int i = 0; i < n; i++){//循环n次
  21. int u = -1, min = INF;
  22. for(int j = 0; j < n; j++){//找到最小的
  23. if(vis[j] == false && d[j] < min){
  24. u = j;
  25. min = d[j];
  26. }
  27. }
  28. if(u == -1) return;
  29. //更新d[]
  30. vis[u] = true;
  31. for(int v = 0; v < n; v++){
  32. if(vis[v] == false && G[u][v] != INF){//没被访问过且可达
  33. if(d[u] + G[u][v] < d[v]){
  34. d[v] = d[u] + G[u][v];
  35. num[v] = num[u];
  36. w[v] = w[u] + weight[v];
  37. } else if (d[u] + G[u][v] == d[v]){
  38. if(weight[v] + w[u] > w[v]){
  39. w[v] = w[u] + weight[v];
  40. }
  41. num[v] += num[u];
  42. }
  43. }
  44. }
  45. }
  46. }
  47. int main(){
  48. scanf("%d%d%d%d", &n, &m, &c1, &c2);
  49. for(int i = 0; i < n; i++) scanf("%d", &weight[i]);
  50. fill(G[0], G[0] + maxn * maxn, INF);
  51. for(int i = 0; i < m; i++){
  52. scanf("%d %d %d", &temp_c1, &temp_c2, &temp_d);
  53. G[temp_c1][temp_c2] = temp_d;
  54. G[temp_c2][temp_c1] = temp_d;
  55. }
  56. Dijkstra();
  57. printf("%d %d",num[c2], w[c2]);
  58. return 0;
  59. }