题目地址:http://pat.zju.edu.cn/contests/pat-a-practise/1003
此题考查最短路径算法dijkstra,代码如下:
#include <stdio.h> const int INF = 1 << 30;//移30位,既可以保证足够大,又可以保证不会因溢出而变成负值! const int N = 500; int matrix[N][N]; int dist[N]; int team[N]; int amount[N]; int count[N]; bool used[N]; int i, j, k; // 参考 http://while2.blogcn.com/articles/robust-dijkstra-and-problems-based-on-shortest-path.html void dijkstra(int n, int s, int e) { dist[s] = 0; amount[s] = team[s]; count[s] = 1; while(true) { int p, min = INF; //招最近的点 for (i = 0; i < n; i++) { if (!used[i] && dist[i] < min) { p = i; min = dist[i]; } } //==INF为起点不与任何点相连的情况,p==e为找到终点的情况,都返回main()函数 if (min == INF || p == e) return; used[p] = true; for (i = 0; i < n; i++) { if (!used[i]) { int cost = dist[p] + matrix[p][i]; if (dist[i] > cost) { dist[i] = cost; amount[i] = amount[p] + team[i]; count[i] = count[p]; } else if(dist[i] == cost) { count[i] += count[p]; if (amount[i] < amount[p] + team[i]) amount[i] = amount[p] + team[i]; } } } } } int main() { //freopen("D:\\test.txt", "r", stdin); int n, m, s, e; while (scanf("%d %d %d %d", &n, &m, &s, &e) != EOF) { for (i = 0; i < n; i++) { scanf("%d", team + i); amount[i] = 0; dist[i] = INF; count[i] = 0; used[i] = false; for (j = 0; j < n; j++) matrix[i][j] = INF; } while (m--) { int a, b, l; scanf("%d %d %d", &a, &b, &l); if (matrix[a][b] > l) matrix[a][b] = matrix[b][a] = l; } dijkstra(n, s, e); printf("%d %d\n", count[e], amount[e]); } return 0; }