//一開始/*amount[start] = team[start];dist[start] = 0;pathcount[start] = 1;u = 0;dist[1] = dist[0] + map[0][1]; // dist[1] == 1dist[2] = dist[0] + map[0][1]; // dist[2] == 2amount[1] = 1 + 2;pathcount[1] = 1;pathcount[2] = 1;u = 1;dist[1] + map[1][2] == 2;//滿足dist[2] == dist[1] _ map[1][2];pathcount[2] = 1 + 1;//此時amount[2] = 0,amount[1] == 3,team[2] == 1;//soamount[2] = 3 + 1;....此時0~2的最短距離和0~2的所有team數目已經求出來了,分別是pathcount[2],amount[2]*/#include <cstdio>#include <iostream>#include <cstdlib>using namespace std;const int MX = 500 + 5;const int INF = 9999999;int map[MX][MX];//記錄兩個點之間的距離sint dist[MX];//記錄從起始點到點i的距離int teams[MX];//記錄每個城市的隊伍數量int amount[MX];//記錄起始點到當前點的最大隊伍數量int pathcount[MX];//記錄從起始點到當前點點的最短路徑數量int v[MX];//標記是否被訪問過int N,M,start,en,dmin;void dijkstra(int start) { amount[start] = teams[start]; dist[start] = 0; pathcount[start] = 1; while (1){ int u,dmin = INF; //都是從0開始,因為第一遍循環會把起始點找出來 for (int i = 0; i < N; i++){ if (v[i] == 0 && dist[i] < dmin){ dmin = dist[i]; u = i; } } //dmin==INF表示所有點已經都遍歷過了 if (dmin == INF) break; //將找到的點標記一下,說明這個點已經訪問過,之后就不要訪問了 v[u] = 1; for (int i = 0; i < N; i++) { if (v[i] == 0) { if (dist[i] > dist[u] + map[u][i]) { dist[i] = dist[u] + map[u][i]; amount[i] = amount[u] + teams[i]; pathcount[i] = pathcount[u]; } else if (dist[i] == dist[u] + map[u][i]) { //如果距離相等就,到達當前的最短路徑數就加1 pathcount[i] += pathcount[u]; //如果之前的最大隊伍數量小于現在的隊伍數量,則進行更新 if (amount[i] < amount[u] + teams[i]){ amount[i] = amount[u] + teams[i]; } } } } } }int main() { while (~scanf("%d%d%d%d",&N,&M,&start,&en)) { for (int i = 0; i < N; i++) { cin >> teams[i]; } //初始化map數組 for (int i = 0; i < N; i++) { dist[i] = INF; for (int j = 0; j < N; j++) { map[i][j] = INF; } } //讀入數據 for (int i = 0; i < M; i++) { int c1,c2,L; cin >> c1 >> c2 >> L; map[c1][c2] = map[c2][c1] = L; } //對所有點進行松弛 dijkstra(start); cout << pathcount[en] << " " << amount[en] << endl; } system("pause"); return 0;}
新聞熱點
疑難解答