Sample Input
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
Sample Output
2 4
#include <iostream> using namespace std; #define INF 1000000 int Graph[500][500]; int TeamNum[500]; // 每个城市拯救队伍数目 int s[500]; // 判断是否已存入该点到S集合中 int Dist[500]; // 从v0到vi的最短路径长度 int TotalTeamNum[500]; // 从v0到k的拯救队伍数 int path[500]; // 最短路径的数目 void dijkstra(int v0, int N) { for(int i = 0; i < N; i++) //初始化 { Dist[i] = Graph[v0][i]; s[i] = 0; // 初始都未用过该点 TotalTeamNum[i] = TeamNum[v0] + TeamNum[i]; path[i] = 1; } // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中 // 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度 // 注意是从第二个节点开始,第一个为源点 s[v0] = 1; //v0加入到顶点集合S Dist[v0] = 0; TotalTeamNum[v0] = TeamNum[v0]; for(int i = 0; i < N; i++) { int min = INF, u = v0; for(int j = 0; j < N; j++) { // 找出当前未使用的点j的dist[j]最小值 // u保存当前邻接点中距离最小的点的号码 if(!s[j] && Dist[j] < min) { u = j; min = Dist[j]; } } s[u] = 1; //将u加入到集合S中 // 更新dist for(int k = 0; k < N; k++) { if(!s[k] && Graph[u][k] < INF && Dist[u] + Graph[u][k] < Dist[k]) { Dist[k] = Dist[u] + Graph[u][k]; TotalTeamNum[k] = TotalTeamNum[u] + TeamNum[k]; path[k] = path[u]; } else if(!s[k] && Graph[u][k] < INF && Dist[u] + Graph[u][k] == Dist[k]) { if(TotalTeamNum[k] < TotalTeamNum[u]+TeamNum[k]) //更新最大值 { TotalTeamNum[k] = TotalTeamNum[u]+TeamNum[k]; } path[k] = path[u] + path[k]; } } } } int main() { int N,M,C1,C2; cin>>N>>M>>C1>>C2; for(int i = 0; i < N; i++) { cin>>TeamNum[i]; } for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { if(i == j) { Graph[i][j]=0; } else { Graph[i][j]=INF; } } } for(int i = 0; i < M; i++) { int a,b,c; cin>>a>>b>>c; Graph[a][b]=Graph[b][a]=c; } dijkstra(C1,N); cout<<path[C2]<<" "<<TotalTeamNum[C2]; return 0; }