某公司於乙城市的銷售點急需一批成品,該公司成品生產基地在甲城市。
甲城市與乙城市之間共有 n 座城市,互相以公路連通。甲城市、乙城市以及其它各城市之間的公路連通情況及每段公路的長度由矩陣M1 給出。
每段公路均由地方政府收取不同額度的養路費等費用,具體數額由矩陣M2 給出。
請給出在需付養路費總額不超過 1500 的情況下,該公司貨車運送其產品從甲城市到乙城市的最短運送路線。
具體數據參見文件:
M1.txt: 各城市之間的公路連通情況及每段公路的長度矩陣(有向圖); 甲城市爲城市Num.1,乙城市爲城市Num.50。M2.txt: 每段公路收取的費用矩陣(非對稱)。
#include<stdio.h> #define UNREACHABLE 9999 #define NODENUM 50 #define MAXCOST 1500 #define LENTHFILE "m1.txt" #define COSTFILE "m2.txt" typedef struct { int nodeNum; int currentLength; int currentCost; }NodeInfo; void pushHeap(NodeInfo *minRootHeap, NodeInfo newNode, int *length); NodeInfo popHeap(NodeInfo *minRootHeap, int *length); void adjustHeap(NodeInfo *minRootHeap, int *length); void sub_adjustHeap(NodeInfo *minRootHeap, int adjustLoc, int *length); int shortestPath(int nodeDist[][NODENUM], int roadCost[][NODENUM], int *prev); void read(int input[][NODENUM], char *filename); void print(int *prev, int location); int main() { int nodeMap[NODENUM][NODENUM], costMap[NODENUM][NODENUM], prev[NODENUM], pathLength; read(nodeMap, LENTHFILE); read(costMap, COSTFILE); pathLength = shortestPath(nodeMap, costMap, prev); if(pathLength) { printf("the shortest distence is:%d\n", pathLength); printf("the order is: "); print(prev, NODENUM - 1); printf("\n"); } else { printf("there is not any path supported\n"); } return 0; } int shortestPath(int nodeDist[][NODENUM], int roadCost[][NODENUM], int *prev) { NodeInfo minRootHeap[NODENUM], activeNode, newNode; int nodeQuantity = 0, distance[NODENUM] = {0}, i; prev[0] = -1; newNode.currentCost = 0; newNode.currentLength = 0; newNode.nodeNum = 0; pushHeap(minRootHeap, newNode, &nodeQuantity); do { activeNode = popHeap(minRootHeap, &nodeQuantity); for(i = 0; i < NODENUM; i++) { if(nodeDist[activeNode.nodeNum][i] != UNREACHABLE) { newNode.nodeNum = i; newNode.currentLength = activeNode.currentLength + nodeDist[activeNode.nodeNum][i]; newNode.currentCost = activeNode.currentCost + roadCost[activeNode.nodeNum][i]; if(newNode.currentCost <= MAXCOST && (!distance[newNode.nodeNum] || newNode.currentLength < distance[newNode.nodeNum])) { pushHeap(minRootHeap, newNode, &nodeQuantity); distance[newNode.nodeNum] = newNode.currentLength; prev[newNode.nodeNum] = activeNode.nodeNum; } } } }while(nodeQuantity); return distance[NODENUM - 1]; } void pushHeap(NodeInfo *minRootHeap, NodeInfo newNode, int *length) { minRootHeap[*length] = newNode; (*length)++; adjustHeap(minRootHeap, length); } NodeInfo popHeap(NodeInfo *minRootHeap, int *length) { NodeInfo minNode = minRootHeap[0]; (*length)--; minRootHeap[0] = minRootHeap[*length]; sub_adjustHeap(minRootHeap, 0, length); return minNode; } void adjustHeap(NodeInfo *minRootHeap, int *length) { int location = (*length - 1) / 2; while(location >= 0) { sub_adjustHeap(minRootHeap, location, length); location--; } } void sub_adjustHeap(NodeInfo *minRootHeap, int adjustLoc, int *length) { NodeInfo tempNode = minRootHeap[adjustLoc]; int child = 2 * adjustLoc + 1; while(child < (*length)) { if(child < (*length - 1) && minRootHeap[child].currentLength > minRootHeap[child + 1].currentLength) { child++; } if(tempNode.currentLength < minRootHeap[child].currentLength) { break; } minRootHeap[(child - 1) / 2] = minRootHeap[child]; child = 2 * child + 1; } minRootHeap[(child - 1) / 2] = tempNode; } void read(int input[][NODENUM], char *filename) { int i, j; FILE *fin; char ch; fin = fopen(filename, "r"); for(i = 0; i < NODENUM; i++) { for(j = 0; j < NODENUM; j++) { fscanf(fin, "%d", &input[i][j]); } } } void print(int *prev, int location) { if(prev[location] == -1) { printf("%d ", location); return; } print(prev, prev[location]); printf("%d ", location); }