题目大意:求最短路的条数,最短路中的权重和的最大值和这条最短路的路线
分析:使用dijkstra算法求出最短路,并且对dijkstra算法进行变化,设起点为s,数量num[MAX_N],权重w[MAX_N],路径path[MAX_N];
当d[i] > d[k] + es[k][i]时,说明这是一条k到i更短的路,那么这时需要进行操作:num[i] = num[k]; w[i] = w[k] + weight[i]; path[i] = k;
当d[i] == d[k] + es[k][i]时,说明这又是一条到i结点的最短路,那么num[i] += num[k]; 那么这时需要考虑权重的大小,选择权重和更大的一条最短路,并修改path和权重w
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int INF = 1000000000; const int MAX_N = 500+5; int es[MAX_N][MAX_N]; int weight[MAX_N]; int d[MAX_N]; bool used[MAX_N]; int path[MAX_N]; int w[MAX_N]; int num[MAX_N]; int V, E, S, D; void dijkstra() { fill(d, d + V, INF); fill(used, used + V, false); d[S] = 0; num[S] = 1; w[S] = weight[S]; while(1) { int k = -1; for(int i = 0; i < V; i++) { if(!used[i] && (k == -1 || d[k] > d[i])) k = i; } if(k == -1) break; used[k] = true; for(int i = 0; i < V; i++) { if(d[k] + es[k][i] < d[i]) { d[i] = d[k] + es[k][i]; num[i] = num[k]; path[i] = k; w[i] = w[k] + weight[i]; } else if(d[k] + es[k][i] == d[i]) { num[i] += num[k]; if(w[i] < w[k] + weight[i]) { w[i] = w[k] + weight[i]; path[i] = k; } } } } } void get_path(int D) { if(D == S) { printf("%d", S); return; } get_path(path[D]); printf(" %d", D); } int main() { cin >> V >> E >> S >> D; for(int i = 0; i < V; i++) { for(int j = 0; j < V; j++) { es[i][j] = INF; } } for(int i = 0; i < V; i++) cin >> weight[i]; int a, b, len; for(int i = 0; i < E; i++) { cin >> a >> b >> len; es[a][b] = es[b][a] = len; } dijkstra(); printf("%d %d\n", num[D], w[D]); get_path(D); return 0; }
作者:kindleheart
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。